From: James S. <jsi...@su...> - 2001-01-17 19:42:12
|
> > static void xxxfb_set_par(struct fb_info *info) > > { > > /* > > * xxx_fb_check_var tested the mode we want to set the hardware to. > > * If it passes it then is set to info->var. Now we set the hardware > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > Who sets this? fbmem.c? Or is there a var argument missing for this function? From fbmem.c : int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info) { int err, oldbpp; if (memcmp(&info->var, var, sizeof(var))) { if ((err = info->fbops->fb_check_var(var, info))) return err; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { oldbpp = info->var.bits_per_pixel; info->var = *var; info->fbops->fb_set_par(info); if (oldbpp != var->bits_per_pixel) { if ((err = fb_set_cmap(&info->cmap, 1, info))) return err; } } var->activate = 0; } return 0; } With this generic set_var function we compare the passed in var with the current var in info. We check if the hardware can handle the mode using par in info but we don't alter par. Once check_var approves AND we want to set the video mode we set info->var to the passed in var and then call set_par. The reason I don't have a par in set_var and pass it to check_var is because I felt it was a waste to create a new par and then throw it away if we just want to check the video mode. Also par could be a array of data structures representing different hardware states the graphics card could be in. The bonus is for fb_find_mode we can just call fbops->fb_check_var directly. > I think it's still safer to use one function for both testing and setting, > since for multi-headed cards both heads depend on each other: > > check_and_test(var, info, test_only) > { > get_lock() /* multi-headed cards only */ > ... do test ... > > if (test_only) { > release_lock() /* multi-headed cards only */ > return; > } > > ... do set ... > release_lock() /* multi-headed cards only */ > } This is fb_set_var in a nutshell minus the locking which we need. In the case of multi-head cards we have more than one fb_info but have one par which is shared between them. If one attempts to change it resolution we can used the values in par to see if it is possible. The one thing we have to be extra careful with is if two processes try to change both resolutions on each display at the same time. The other question is what to do in the following situation: display A in mode a display B in mode b VC switch display A in mode c display B in mode d When we change to mode c it is acceptable to mode b but not to mode d. Do we disallow the VT switch? > > void xxxfb_imageblit(struct fb_info *p, unsigned int width, > > unsigned int height, unsigned long *image, > > int image_depth, int dx, int dy) > > { > > } > > I still like to have the possibility to blit an array of images, for drawing > multiple characters (fbcon_putcs()). Drawing individual characters is too slow > on some hardware (e.g. Amiga bitplanes: each 8-pixel wide character needs to > access 1 byte in each plane, while drawing 4 (AGA, 32-bit wide bus) or 2 (ECS, > 16-bit wide bus) characters needs the same number of memory accesses. I agree. fbcon_putcs would have to be smart in how to construct a image to pass to the blit function. The blit function can take in any size image. That is why the width and height fields. If done right you can draw huge images to the display in very short time. For the generic packed pixel case I word align the data and then transfer unsigned long size data at a time to the graphics card. On a 32 bit machine in 8 bpp then means 4 pixels are drawn in one cycle. I'm sure we can do the same thing for Amiga interleaved bitplanes. I also figured out really fast really fast rectfill and copyarea for ilbm. Since each plane is a 0 or 1 at position X in the pixel and each plane comes afetr each other in video memory we can for each plane work with a bunch of 0s or just a bunch of 1s. P.S I never did figure out how Amiga interleaved bitplanes are layed out. How do you fill in one pixel of some color to the display? Once I have that figured out I can write a really fast rectfill, copyarea, and imageblit for it. > > /* This should give a reasonable default video mode */ > > if (!mode_option) > > mode_option = "640x480@60"; > > Not needed. fb_find_mode() will do this automagically if mode_option is NULL. Okay. Updated. > > fb_pan_display: xxxfb_pan_display, > > fb_rectfill: xxxfb_rectfill, /* optional */ > > fb_copyarea: xxxfb_copyarea, /* optional */ > > fb_imageblit: xxxfb_imageblit, /* optional */ > > fb_ioctl: xxxfb_ioctl, /* optional */ > > fb_mmap: xxxfb_mmap, /* optional */ > > }; > > Aren't xxxfb_{rectfill,copyarea,imageblit} mandatory, because fbcon-* will go > away? Yes but for the standard packed pixel non accelerated graphics cards we have cfbrectfill, cfbcopyarea, and cfbimageblit to use. If the driver doesn't provide these functions then we use these cfb* functions. I even stored each function in a seperate file just in case we run into cards that support one or two of the three accelerated functions. |