Upload
gwenda-blankenship
View
221
Download
1
Tags:
Embed Size (px)
Citation preview
CS 686: Programming SuperVGA Graphics Devices
Introduction: An exercise in working with graphics file formats
Raster Display TechnologyThe graphics screen is a two-dimensional array of picture elements (‘pixels’)
Each pixel’s color is an individually programmable mix of red, green, and blue
These pixels are redrawn sequentially, left-to-right, by rows from top to bottom
Graphics programs
• What a graphics program must do is put appropriate bit-patterns into the correct locations in the VRAM, so 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)
• Some types of applications also need to use extra VRAM (for multiple displays, or for “special effects” like computer game animations)
How ‘truecolor’ works
R
B
G
alpha red green blue081624
pixel
longword
The intensity of each color-component within a pixel is an 8-bit value
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: $ make vram.o• 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
• Some special software is needed (‘lrmi’)
Class demo: ‘pcxphoto.cpp’
• First: several system-setup requirements
• Some steps need ‘root’ privileges (‘sudo’)
• Obtain demo sources from class website
• Install the ‘mode3’ program (from svgalib)
• Compile character device-driver: ‘vram.c’
• Create ‘dev/vram’ device-node (read/write)
• Start Linux in ‘text mode’ (need to reboot)
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 will study those registers
• For now, we just ‘reuse’ vendor routines
• Such routines are built into VGA firmware
• However, invoking them isn’t trivial (since they weren’t designed for Linux systems)
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 (can search web)
Microsoft’s ‘.pcx’ file-format
FILE HEADER (128 bytes)
IMAGEDATA
(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 0x29Byte-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 will VRAM go?
• We decided to use graphics mode 0x013A
• It’s a ‘truecolor’ mode (32bpp)
• 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 address-range: 0xB0000000-0xB2000000
Virtual Memory Layout
Linux kernel
stack
VRAM
code and data
runtime library
0x08048000
0x40000000
0xB0000000
0xC0000000
userspace(3GB)
kernelspace(1GB)
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 Algorithmstruct { 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-componentpixel |= ( avg << 8 ); // g-componentpixel |= ( avg << 0); // b-componentvram[ address ] = pixel; // write to screen