On Feb 21, 2008, at 2:09 AM, Oliver Fromme wrote:
Actually I don't plan to use a bitblit function at all,
because it's not really feasible in standard VGA modes.
What do you mean by that?
Maybe we have different understandings what bitblit means.
My understanding is that bitblit is a raster operation
between two bitmaps (typically "AND" and "OR" operations
for masking regions). I've done such things on the Amiga
20 years ago (hardware-assisted by a coprocessor called
"Blitter").
I think they may fundamentally be the same thing. The bitblt
I refer to is Bit Block Transfer. While the bitblt API could
support bit-wise operations while it's copying, it's main
purpose is to move a bit-array (tile/sprite) from RAM to VRAM,
or possibly between VRAM locations. Everything that needs to
be done can be done with a bitblt. It also happens to be the
operation that was first accelerated...
The abstraction is in the details of how a bit-mask or image
map needs to be written to VRAM to have it appear as a char.
or an image on the screen.
I implemented bitblt for VGA for vtc(4). Take a look at:
http://people.freebsd.org/~marcel/vga.diff
[patch extracted from the tty branch in Perforce]
That's good code, but how does it help abstracting the
hardware? I think I might just fail to see the obvious
because I haven't had enough coffee in the morning yet.
The higher lever TTY code simply calls bitblt with a
bit mask of the glyph to be printed and doesn't need to
know about the details of the display. As such, simple
console output works at any resolution and with any
color depth.
At the same time the VGA driver is abstracted from any
high-level details, like fonts or character sets. This
means that it's easy to write an accelerated driver for
some graphics hardware. You simply implement mode
setting and bitblt and you're good to go.
For example, lets say there's a function to draw a
rectangle (in fact there _is_ such a function in my code).
The Forth code to draw a rectangle covering the whole
screen at 640x480 would look like this:
480 640 0 0 vrect
The FICL word pops the parameters from the Forth stack
and calls a function gfx_rect(). This will go through
an abstraction switch so it calls an appropriate function
depending on the bitmap format of the current mode,
i.e. there will be gfx_planar4_rect(), gfx_linear8_rect()
and gfx_true24_rect(). Each of these functions implements
the graphics operation in the most efficient way for the
particular bitmap format.
How would the above work with a bitblit function, exactly?
You bitblt the 4 edges. I didn't say it was the most
performance optimal thing to do. I only said that it
can be abstracted that way.
Rectangles are better abstracted with a linedraw
primitive, but unless you really want generic line
drawing capabilities in the loader, it's probably not
worth implementing it....
That would be possible. But then there will be other
problems. For example, lets say that the i386 loader
decides to use 640x480 @4bit, and the sparc64 loader
decides that 1152x900 @8bit is "best".
The Forth code clearly needs a way to query the resolution
and bit depth that was set, so it can chose an appropriate
background image. It might also have to chose a different
font.
Yes, that's generally the difficulty with graphics.
So the bottom line is that the Forth code cannot easily
be abstracted from the hardware anyway.
Well, it cannot be abstracted from the graphics settings,
but it is abstracted from the hardware.
True. I agree.
What I meant to say was this: The hardware dictates which
graphics settings are available. So the Forth code depends
on the hardware indirectly. But of course it shouldn't
have to know anything about the hardware itself.
Yes. My vtc(4) driver, which puts graphics support in the
kernel, is having the same problems with bitmaps. I have
a nice logo (the 4.4 daemon: see
http://www.mckusick.com/beastie/shirts/source.html), but
I only have it for the standard VGA 4-bit color mode. I need
a separate one for 16-bit and/or 256-bit colors...
There's also a problem when VESA support is added: It's
not possible to reliable detect what resolutions the
attached monitor supports, so by default we must use
640x480 anyway, even if VESA support is present and the
hardware can do 1600x1200 or whatever. Using a higher-
resolution mode is a decision that needs to be made by
the admin, not by the loader, so there must be a way
for the Forth code to request a specific resolution.
This does not have to be done in Forth. If in Forth you
simply say "Switch to graphics" and the platform code
looks up an environment variable for the actual mode,
then the user is still control of the resolution. In
fact, this is much more user friendly than having the
user edit Forth code, which he/she may not...
You're completely right, of course.
I didn't mean to say the the user will have to edit Forth
code (I wish loader would use a different language, but
that's a different story).
:-)
My plan is that there will be a configuration snippet
(maybe in loader.conf, maybe separate, I haven't spent
many thoughts on it yet). It will contain things such
as the file name of the background image, font, colors
for the text, position of the menu, etc. It should
also contain the desired resolution (if not the default).
It should be fairly easy to edit.
Yeah. Something along those lines should do it.
The Forth code will only have to be edited if the user
wants to create something completely different that's
not covered by the configuration settings.
So the situation will be similar to what it is now in
regards to the text menu: The use can select whether
he wants the ASCIII beastie or the big "FreeBSD" text,
and whether he wants it in color or b/w. He can also
disable the menu completely. But if he wants to make
major changes, such as adding new menu items, or changing
the ASCII logo, he'll have to dig into the Forth code.
What do you think?
I think that sounds good. I do have another datapoint.
I leave it up to you whether that's something that needs
to be considered or not:
EFI supports multiple consoles. In other words, the
EFI console can be both the display and the serial
line at the same time. Clearly, graphics mode is
something that you generally cannot duplicate over
the serial line. However, modulo the logo and
background, if the graphics console is like a text
console or serial console, then you can still have
them both. The serial console simply doesn't get
copied the logo and background, but since everything
else is text anyway, this should not be a problem.
My ia64 machines use serial consoles, because
syscons hasn't been ported (and I'm not planning to
yet). However, it would be great if we could get the
EFI loader working in graphics mode already and
it would be especially great if that doesn't break the
dual console setting in EFI.
The question before us is: worth a try or not worth
it...
Basically I agree that whatever graphics support is added to
the loader should be possible to add to the kernel later,
too. In fact that might be the best way to solve the
problem that VESA modes cannot be used with FreeBSD/amd64:
Let the loader switch to the desired VESA mode and give
all information necessary to access the frame buffer to
the kernel, so the VESA BIOS is out of the way.
Agreed. This also works on powerpc or sparc64, where
the firmware sets the graphics mode and all we have to
do is make use of it. It's all part of the vtc(4) driver effort
too: we don't have to have a driver that knows how to set
the mode. All that suffices is a driver that can figure out
the mode in which the hardware is, and knows how to
use the mode.
So, the question is: how important is it for the user to
be able to tweak it all.
If the user had no way of specifying a resolution, then
there would be no point in supporting VESA, because there
wouldn't be a way to specify a VESA mode at anything else
than 640x480.
If we're going to use the loader to set the graphics mode
for the kernel, then obviously it becomes more important
for the loader to be able to switch to modes the user likes
best...
ell, personally I would also like to be able to use the
capabilities of my hardware. My main "workstation" at home
is a notebook. When using the default VGA resolution of
640x480, the hardware scales it up to the TFT resolution,
and it doesn't do a particularly good job at it ... It's
butt ugly and distorted. As a user, I would certainly
welcome an option (in loader.conf or whatever) that enables
me to select a better resolution.
Is that like a toddler going nuts over candy?
Yes and no. I can image that the user wants control over
the desktop. Power to the people. But here we're talking
about the boot process. For Joe User nothing more than
a waiting period. What does it matter, really, that a nice
logo is a bit distorted? Would it be nicer if we could avoid
the scaling? Yes, definitely. But it's not the first priority.
The graphics world is one with many pitfalls, obstacles
and controversies. I think it's best to get something basic
off the ground first. I think performance is not a concern.
Once you have the basic functionality, you'll also have a
wishlist of things you want to do better; performance one
of them in all likelyhood.
The apparently simple problem of avoiding the scaling
means that you need to understand much more of the
graphics hardware and need to support DDC so that you
know the capabilities and restrictions of the system.
My Sony Vaio doesn't scale for example. It always has
the resolution set to the native of 1024x768 and simply
shows a 640x480 image in the center. Ideally you use
the native resolution, but if you avoid borders and
backgrounds and only use a simple logo in the center,
then you won't even notice...
Anyway: those are just my views. Not at all important
in the grand scheme of things, because in the end we
probably all want the same thing. It's just the getting
there where we differ on :-)
Of course, it would be pretty easy to implement both.
So you have one function that simply set the mode that
the driver thinks is best (that would be a 640x480 mode
in the i386 case). And a second function that takes
resolution and depth as parameters, in order to switch
to a specific mode. There could be a special depth
value (0 or -1) indicating "I don't care, just give
me whatever you can at this resolution".
Yes. If common code doesn't care about the setting, then
it's easy enough to allow the user to pick the setting
of choice...
Right. My goal is that it should work that way.
There's an in-between. The loader exists only to load
a kernel. We want it to look nice, but there's no
reason to tweak resolutions so that you can see the
kernel being loader in HD. The platform, which
includes the firmware, knows best which resolutions
look good.
I bet there will be people who disagree with the firmware
about which resolution looks good.
True. But in that case you want to change the setting in
the firmware, not in the loader. If you want to depend on
the firmware/BIOS for mode setting then you also have to
depend on the Firmware/BIOS to allow the user to select
a setting of choice. Here too the loader then pretty much
as to work with whatever it gets thrown at it.
Hm. I'm not sure I understand.
Lets take an example: By default the loader decides to
use 640x480 @4bit (or maybe @8bit if VESA support present).
Now some user wants to use VESA mode 1024x768 instead.
And yet another user would prefer Mode-X 360x480 @8bit
with his own 256-color background image. How are these
users supposed to do that? There's no way in the BIOS
to tune anything. I think the most appropriate way would
be a setting in loader.conf or another configuration file.
You're right. I was thinking too much about Open Firmware.
On PCs the user typically has no way to set a graphics mode,
so the loader is the place to do it. Sorry for the confusion.
PS: I just took a few minutes to make yet another screen
design, it's based on the design of the www.freebsd.og
web pages. It includes both the logo and the daemon
mascot:
http://www.secnetix.de/olli/FreeBSD/vloader/screenshot5.png
Another great image. I think we're finally moving into the 20th
century :-)
--
Marcel Moolenaar
[EMAIL PROTECTED]
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"