CS 686: Programming SuperVGA Graphics Devices Introduction: An exercise in

advertisement
CS 686: Programming
SuperVGA Graphics Devices
Introduction: An exercise in
working with graphics file formats
Raster Display Technology
The graphics screen is a two-dimensional array of picture elements (‘pixels’)
These pixels are redrawn sequentially, left-to-right, by rows from top to bottom
Each pixel’s color is an individually programmable mix of red, green, and blue
Special “dual-ported” memory
VRAM
CRT
CPU
16-MB of VRAM
RAM
2048-MB of RAM
Graphics programs
• What a graphics program must do is put
appropriate bit-patterns into the correct
locations in the VRAM, such that the CRT
will show an array of colored dots which in
some way is meaningful to the human eye
• So the programmer must understand what
the CRT will do with the contents of VRAM
How much VRAM is needed?
• This depends on (1) the total number of pixels,
and on (2) the number of bits-per-pixel
• The total number of pixels is determined by the
screen’s width and height (measured in pixels)
• Example: when our “screen-resolution” is set to
1280-by-960, we are seeing 1,228,800 pixels
• The number of bits-per-pixel (“color depth”) is a
programmable parameter (varies from 1 to 32)
• Certain types of applications also need to use
extra VRAM (for multiple displays, or for “special
effects” like computer game animations)
How ‘truecolor’ works
24
longword
alpha
16
8
red
green
R
G
0
blue
B
pixel
The intensity of each color-component within a pixel is an 8-bit value
Intel uses “little-endian” order
VRAM
0
1
2
B
G
R
3
4
5
6
B
G
R
Video Screen
7
8
9
10
B
G
R
Some operating system issues
•
•
•
•
•
•
•
•
Linux is a “protected-mode” operating system
I/O devices normally are not directly accessible
On Pentiums: Linux uses “virtual memory”
Privileged software must “map” the VRAM
A device-driver module is needed: ‘vram.c’
We can compile it using: $ mmake vram
Device-node: # mknod /dev/vram c 99 0
Make it ‘writable’: # chmod a+w /dev/vram
VGA ROM-BIOS
• Our graphics hardware manufacturer has
supplied accompanying code (‘firmware’)
that ‘programs’ VGA device components to
operate in various ‘standard’ modes
• But these firmware routines were not
written with Linux in mind: they’re for
interfacing with ‘real-mode’ MS-DOS
• So special software is needed: ‘int86.cpp’
What is ‘int86.cpp’?
• This is ‘boilerplate’ code that we can ‘link’
with all of our Linux graphics applications
• It invokes some kernel services provided
by our ‘dosio.c’ device-driver which set up
a ‘pre-boot execution-environment’ (PXE)
allowing Linux to run firmware-routines in
‘virtual-8086’ mode (via the ‘vm86()’ call)
• Later we will discuss how it works, but for
now we just use it to get on with our demo
In-class demo: ‘pcxphoto.cpp’
• First: several system-setup requirements
• Some steps need ‘root’ privileges (or ‘sudo’)
• Create device-nodes in ‘/etc/udev/devices’:
– ‘/etc/udev/devices/dos’ (read-only)
– ‘/etc/udev/devices/vram’ (read/write)
• Restart Linux in ‘text mode’ (GRUB boot-menu)
• Obtain demo sources from our class website
• Compile and install our character-mode Linux
device-driver modules: ‘dosio.c’ and ‘vram.c’
Typical ‘program-structure’
Usual steps within a graphics application:
–
–
–
–
Initialize video system hardware
Display some graphical imagery
Wait for a termination condition
Restore original hardware state
Hardware Initialization
•
•
•
•
•
•
The VGA system has over 300 registers
They must be individually reprogrammed
Eventually we shall study those registers
For now, we just ‘reuse’ vendor routines
Such routines are built into VGA firmware
But invoking them isn’t trivial (since they
weren’t designed for a Linux environment)
Obtaining our image-data
•
•
•
•
•
•
•
Eventually we want to ‘compute’ images
For now, we ‘reuse’ pre-computed data
Data was generated using an HP scanner
It’s stored in a standard graphic file-format
Lots of different graphic file-formats exist
Some are ‘proprietary’ (details are secret)
Other formats are public (search the web)
BitMaP (.bmp) file-format
FILE HEADER
INFO SECTION
Optional color palette
IMAGE
DATA
(usually uncompressed)
This is an image-format often used by Microsoft Windows
PiCture eXchange (.pcx) format
FILE HEADER (128 bytes)
IMAGE
DATA
(compressed)
COLOR PALETTE
(768 bytes)
Run-Length Encoding (RLE)
• A simple technique for ‘data-compression’
• Well-suited for compressing images, when
adjacent pixels often have the same colors
• Without compression, a computer graphics
image-file (for SuperVGA) would be BIG!
• Exact size depends on screen-resolution
• Also depends on the display’s color-depth
• (Those parameters are programmable)
How RLE-compression works
If multiple consecutive bytes are identical:
example:
0x29 0x29 0x29 0x29 0x29
(This is called a ‘run’ of five identical bytes)
We “compress” five bytes into two bytes:
the example compressed: 0xC5 0x29
Byte-pairs are used to describe ‘runs’:
Initial byte encodes a ‘repetition-count’
(The following byte is the actual data)
Decompression Algorithm
int
i = 0;
do {
read( fd, &dat, 1 );
if ( dat < 0xC0 ) reps = 1;
else { reps = (dat & 0x3F); read( fd, &dat, 1 ); }
do { image[ i++ ] = dat; } while ( --reps );
}
while ( i < npixels );
Standard I/O Library
• We call standard functions from the C/C++
runtime library to perform i/o operations on
a device-file (e.g., vram):
open(), read(), write(), lseek(), mmap()
• The most useful operation is ‘mmap()’
• It lets us ‘map’ a portion of VRAM into the
address-space of our graphics application
• So we can ‘draw’ directly onto the screen!
Where shall VRAM go?
•
•
•
•
•
•
We decide to use graphics mode 0x0121
It’s a ‘truecolor’ mode: 32 bits-per-pixel
It uses a screen-resolution of 640x480
Size of VRAM needed: 640*480*4 bytes
So we ‘map’ 2-MB of VRAM to user-space
We can map it to this user address-range:
0xA0000000-0xA0200000
Virtual Memory Layout
kernel
space
(1GB)
Linux kernel
stack
VRAM
0xC0000000
0xA0000000
user
space
(3GB)
runtime library
code and data
0x40000000
0x08048000
How to compile our demo
• The demo program is ‘pcxphoto.cpp’
• It needs to include a header: ‘pcx.h’
• It needs to read a datafile: ‘issxmas.pcx’
• It needs to be linked with ‘int86.cpp’
• It needs to include the header: ‘int86.h’
• Compile it with the GNU C++ compiler:
$ g++ pcxphoto.cpp int86.cpp –o pcxphoto
Programming Project #1
• Write an analagous demo-program that
will display an image in .bmp file-format
• The image-file is named ‘fwright.bmp’
• You will need to utilize a different graphics
display mode: 1024-by-768 (mode 0x123)
• You will need a different header: ‘bmp.h’
• You will need a different image-algorithm
Exercise: Color-to-Grayscale
• Sometimes a color image needs to be
converted into a ‘grayscale’ format
• Example: print a newspaper photograph
(the printing press only uses ‘black’ ink)
• How can we ‘transform’ color photos into
black-and-white format (shades of gray)?
• ‘gray’ colors use a mix of red+green+blue,
these components have EQUAL intensity
Color-conversion Algorithm
struct { unsigned char r, g, b; } color;
int avg = ( 30*r + 49*g + 11*b )/100;
color.r = avg; color.g = avg; color.b = avg;
long
pixel = 0;
pixel |= ( avg << 16 );
// r-component
pixel |= ( avg << 8 );
// g-component
pixel |= ( avg << 0);
// b-component
vram[ address ] = pixel; // write to screen
In-class exercise
• Revise the ‘pcxphoto.cpp’ program so that
it will display (1) the ‘color-table’, and then
(2) the scanned photograph, as ‘grayscale’
images (i.e., different intensities of gray)
Download