You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
(1) |
Apr
(104) |
May
(81) |
Jun
(248) |
Jul
(133) |
Aug
(33) |
Sep
(53) |
Oct
(82) |
Nov
(166) |
Dec
(71) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(121) |
Feb
(42) |
Mar
(39) |
Apr
(84) |
May
(87) |
Jun
(58) |
Jul
(97) |
Aug
(130) |
Sep
(32) |
Oct
(139) |
Nov
(108) |
Dec
(216) |
| 2003 |
Jan
(299) |
Feb
(136) |
Mar
(392) |
Apr
(141) |
May
(137) |
Jun
(107) |
Jul
(94) |
Aug
(262) |
Sep
(300) |
Oct
(216) |
Nov
(72) |
Dec
(94) |
| 2004 |
Jan
(174) |
Feb
(192) |
Mar
(215) |
Apr
(314) |
May
(319) |
Jun
(293) |
Jul
(205) |
Aug
(161) |
Sep
(192) |
Oct
(226) |
Nov
(308) |
Dec
(89) |
| 2005 |
Jan
(127) |
Feb
(269) |
Mar
(588) |
Apr
(106) |
May
(77) |
Jun
(77) |
Jul
(161) |
Aug
(239) |
Sep
(86) |
Oct
(112) |
Nov
(153) |
Dec
(145) |
| 2006 |
Jan
(87) |
Feb
(57) |
Mar
(129) |
Apr
(109) |
May
(102) |
Jun
(232) |
Jul
(97) |
Aug
(69) |
Sep
(67) |
Oct
(69) |
Nov
(214) |
Dec
(82) |
| 2007 |
Jan
(133) |
Feb
(307) |
Mar
(121) |
Apr
(171) |
May
(229) |
Jun
(156) |
Jul
(185) |
Aug
(160) |
Sep
(122) |
Oct
(130) |
Nov
(78) |
Dec
(27) |
| 2008 |
Jan
(105) |
Feb
(137) |
Mar
(146) |
Apr
(148) |
May
(239) |
Jun
(208) |
Jul
(157) |
Aug
(244) |
Sep
(119) |
Oct
(125) |
Nov
(189) |
Dec
(225) |
| 2009 |
Jan
(157) |
Feb
(139) |
Mar
(106) |
Apr
(130) |
May
(246) |
Jun
(189) |
Jul
(128) |
Aug
(127) |
Sep
(88) |
Oct
(86) |
Nov
(216) |
Dec
(9) |
| 2010 |
Jan
(5) |
Feb
|
Mar
(11) |
Apr
(31) |
May
(3) |
Jun
|
Jul
(7) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
| 2012 |
Jan
|
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2013 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Antonino D. <ad...@po...> - 2003-01-11 05:22:34
|
On Sat, 2003-01-11 at 03:39, James Simmons wrote:
>
> > > I thought about this. Originally I did have this function but removed it.
> > > WHat do you think Geert?
> >
> > Yes, that's OK.
> >
> > But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> > fb_image.data as well. IIRC, all (most?) current clipping implementations
> > modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.
>
> Good point. Of course we could ignore pieces of data in that image instead
> of altering the data. Altering the entire data would be expensive.
>
> > > > The other option (which I don't like) is just to check the passed
> > > > fb_var_screeninfo in the put_var ioctl against the current console
> > > > window size. But this is not foolproof as we will not be sure of the
> > > > resulting window size _after_ the fb_set_var() call.
> > >
> > > Yuck!!! The other way is better.
> >
> > Well, in between the calls to fb_ops.fb_check_var() and fb_ops.set_par() you
> > can still perform that check. But it's indeed ugly.
>
> Altering to the framebuffer via /dev/fb that would effect the tty should
> not remain after the final close of /dev/fb. Instead the console should
> reset to its previous state before we first opened /dev/fb.
>
Right :-) I believe this is nearer the correct solution. Clipping is
typically used to maximize graphics/video bandwidth, but fbcon is using
it to "cover up" possible bugs in the code.
If we can have a correctly working fbcon, without the clipping code, it
will be proof to its robustness.
So, basically, on the first open we save xres, yres, xres_virtual,
yres_virtual and bits_per_pixel, and restore them on the last close, is
this correct? Any other parameters that will affect the actual and
virtual window size?
Tony
|
|
From: Antonino D. <ad...@po...> - 2003-01-11 05:21:58
|
On Sat, 2003-01-11 at 03:23, James Simmons wrote: > > > I've thought of that also, packing the data according to the pixel depth. > > Actually I was think more along the image depth. The largest the penguin > logo gets is 224 colors. Meaning the largest image.depth is 8 bits per > pixel. I do agree it is messy to pack the logo data. So for say the 16 > color logo (4 bpp) putting two pixels worth of data into each byte and > then seperating it out would be time consuming. The only reason I was > thinking this way is because of userland using the cursor means imageblit > is visible to userland. That's why we don't need to support software cursor routines, which implies that imageblit will not be exposed to user space. It's impractical to do that in kernel space anyway because you need lot's of additional code: 1.You have to constantly save and restore the screen underneath the cursor. In the console we can cheat because we know the current character underneath the cursor and movement of the cursor is granulated anyway, per character instead of per pixel. 2. Imageblit has to support more ROP's. Otherwise, the user will be stuck with a rectangular cursor. In fbcon, again, we can cheat, because we always know that any given character is just made up of 2 colors, the background and the foreground. So it's easy to do bit operations using the cursor image, the cursor mask, and the font bitmap of the character underneath the cursor. In user space, expect the image beneath the cursor to be composed of > 2 colors. 3. Optionally, imageblit has to support color expansion other than mono->framebuffer format in case the cursor image depth != framebuffer depth. Note, imageblit is limited by length of info->pseudo_palette, so the app cannot pass a cursor image whose depth is equal to the framebuffer depth (unless bpp <= 4bpp). 4. Imageblit will not be able to practically support more than 256 colors at a time and still do it efficiently. Either we change the formatting of the data to match the native framebuffer format, which is the most efficient but requires intimate knowledge of the hardware, or change it into directcolor format. Changing it to directcolor format means we have to reconstruct each pixel from the cmap. This is just too slow. So only drivers with hardware cursor support need to expose it to userspace. And we keep imageblit private to fbcon. > > > a. Prepare logo data so each pixel of data is in directcolor format (if > > we will use the cmap), so depth corresponds to framebuffer depth, and > > data is packed. > > The depth doesn't have to be the same as the framebuffer depth. The logo > data is in terms of color map indices. I did think in terms of packed data > tho. > So how will the driver know how the logo data is packed if it's not based on the framebuffer depth? Unless you have conditionals like: if (!(8 % var->bits_per_pixel) && var-bits_per_pixel <= 8) pixels_per_byte = 8/var->bits_per_pixel; /* 1, 2, 4, 8 bpp*/ else pixels_per_byte = 1; Or: pixels_per_byte = 1 /* always */ The latter is so much simpler. Or if you want to pack 1-8 bpp entirely, then be willing to add code for packing 3, 5, 6, 7 bpp. > > d. Get each color component from the cmap data. > > > > e. Recreate pixel data based on var.[color].offset and > > var.[color].length. > > Yuck no. Doing a fb_set_cmap should handle that before we call > xxxfb_imageblit. Then xxxfb_imageblit only has to take the data in > the logo data as indices of the color map. Of > Which is what the current code is already doing, building a temporary pseudo_palette, albeit without the driver's notice. By extending the pseudo_palette to 256 entries, we can let the driver build it on its own. > > f. Write the pixel data in packed form to the framebuffer. > > > Whereas, with the current approach: > > > > a. Prepare logo data such that each pixel corresponds to one byte. > > > > b. Pass the structure to cfb_imageblit. > > > > c. Read color information from pseudopalette if directcolor/truecolor. > > > > d. Write the pixel data in packed form to the framebuffer. > > I was think the same way except for the idea of more than one color > indices per byte for less than 8 bpp modes. > Same argument as the above. Too much complexity, too little gain. > > Secondly, indexing the cmap instead of the pseudo_palette means that > > cfb_imageblit has to know the native framebuffer format. > > No indexing the cmap. Instead call fb_set_cmap before we call > xxxfb_imageblit. Personally I think we should call fb_set_cmap always. > Only if the pseudo_palette is extended to > 16 entries, or some exotic hardware requires it. Otherwise, it's useless besides setting the color register. In any case, it's an easy fix. > > I would rather have everything refer to > > the pseudopalette, regardless of the visual format. This will be better > > especially for some of the corner cases, like monochrome cards with > > bits_per_pixel = 8. > > It works pretty good for for any pack pixel type modes. Now for planar > cards this isn't the case. Ideally struct fb_cmap should have contained > a I don't see a problem here. vga16fb is planar, and logo drawing works just fine. > > unsigned long pixel; > > field. Like X does. It does not and changing that would break things :-( > Isn't that what info->pseudo_palette is used for? Tony |
|
From: Antonino D. <ad...@po...> - 2003-01-11 05:21:19
|
On Sat, 2003-01-11 at 02:18, James Simmons wrote: > > > Here's an improved GTF implementation. I was a bit delayed because I > > was trying to find a way to do square roots without using floating > > point. The diff is against linux-2.5.54 + your latest fbdev.diff. > > Applied. > > > but is more or less usable. Tested with i810fb and rivafb. (For rivafb, > > I have to use a hacked version. The latest one does not work for the > > riva128). > > What hack did you do? That is based on the latest riva driver from 2.4.2X. > I just combined the old riva_hw.c in linux-2.5.52 with the new fbdev.c code. Not too sure why, either the newest riva_hw.c has dropped support for old hardware, or we are using it incorrectly. If I'm to guess, the new riva_hw.c did not come from linux-2.4.20, but probably from Xfree86? > > BTW, I downloaded the source code of read-edid, and it seems that the > > following monitor limits are parsable from the EDID block: HorizSync, > > VertRefresh, DotClock, and GTF capability. We may change info->monspecs > > to match that. Also, the EDID contains a list of supported modes, but > > there's only 4 of them(?). > > I figured monspec would have to be improved. I'm looking into the EDID > info right now. I'm also looking at read-edid. Next I need to figure out > how to use i2c to get this info. > Good luck :-) Tony |
|
From: Antonino D. <ad...@po...> - 2003-01-11 05:20:48
|
On Sat, 2003-01-11 at 03:43, Geert Uytterhoeven wrote:
> On Fri, 10 Jan 2003, James Simmons wrote:
> > > I think we still have several corner cases, such as TRUECOLOR with bpp
> > > <= 8, I'm not sure if that works.
> >
> > The matorx millenium has such a mode. So such things do exist.
> >
> > > - if (image->depth == 1) {
> > > + if (image->depth == 0) {
> >
> > P.S
> >
> > I'm just not to crazy about the depth equal zero thing. I just pitcure
> > developers having a hard time with it.
>
> Monochrome color expansion just works differently: it expands the zeroes and
> ones in a bitmap based on fg_color and bg_color, while image drawing draws an
> image containing colormap indices to the frame buffer.
>
> Do you have a better suggestion?
>
If James is a bit skeptical about this, how about doing it this way:
If image.fg_color and image.bg_color == 0, then each byte of image.data
is an index to the pseudo_palette, or the actual pixel, whatever the
case may be. Otherwise, image.data is a monochrome bitmap that should
be expanded using fg_color and bg_color.
No other changes will be needed except that mono cards have to test for
fg_color and bg_color, and we need to memset the fb_image structure to 0
in fb_set_logo(). Non-mono cards will continue testing for image.depth.
Do you think this will work? The only problem I can think of is a color
expansion request where both bg and fg is 0.
Or to totally eliminate the above possibility, add an extra field in
struct fb_image to denote color expansion vs logo drawing. Again, only
mono cards will need to do this test.
Tony
|
|
From: James S. <jsi...@in...> - 2003-01-11 00:01:21
|
> Hopefully it's the final installment for the GTF implementation. > > The fb_get_mode() function checks for a bit in 'flags' (FB_IGNOREMON) so > it will generate GTF timings regardless of the validity of > info->monspecs. This way, drivers can still use GTF even if they don't > have the operational limits of the monitor. They'll just decide what is > a practical safe limit. Applied. |
|
From: Geert U. <ge...@li...> - 2003-01-10 19:50:05
|
On Fri, 10 Jan 2003, James Simmons wrote:
> > > I thought about this. Originally I did have this function but removed it.
> > > WHat do you think Geert?
> >
> > Yes, that's OK.
> >
> > But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> > fb_image.data as well. IIRC, all (most?) current clipping implementations
> > modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.
>
> Good point. Of course we could ignore pieces of data in that image instead
> of altering the data. Altering the entire data would be expensive.
Actually I thought about modifying the fb_image.data pointer only. But indeed,
for monochrome expansion you may have to modify the data, since pixel
boundaries in a bitmap don't correspond to byte boundaries.
Alternatively, if fb_image would countain sx and sy fields (cfr. fb_copyarea),
we can just alter (a copy of) sx and sy when clipping.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: Jon S. <jon...@ya...> - 2003-01-10 19:49:57
|
I have been getting requests for this. It is from the svgalib people..... --- Jon Smirl <jon...@ya...> wrote: > Date: Sun, 5 Jan 2003 21:34:42 -0800 (PST) > From: Jon Smirl <jon...@ya...> > Subject: Resetting secondary video adapter > To: dri-devel <dri...@li...> > > I ran across this program for resetting secondary > adapters. > http://www.arava.co.il/matan/svgalib/hypermail/1660.html > Inside of the download you can build vbios.vm86. The > vm86 version worked on my Rage128. The x86emu > version > runs, but doesn't reset the adapter. > > I had tried hacking this code out of X86 without > success. I also tried moding lrmi. lrmi needs more > of > the bios vectors, entry points, etc set up. > > There are later versions of x86emu here > ftp://ftp.scitechsoft.com/devel/x86emu but I can get > them to build. > > On a related note, in redhat-config-xfree86 the > probe > monitor button is always disabled on the secondary > adapter. This is because redhat-config-xfree86 uses > ddcprobe to do the configing. ddcprobe uses lrmi > which > can't handle a secondary adapter. > > The code in vbios.vm86 could probably be merged into > ddcprobe/lrmi to make it work. Then it would be easy > to give ddcprobe a reset parameter too. > > ===== > Jon Smirl > jon...@ya... > > __________________________________________________ > Do you Yahoo!? > Yahoo! Mail Plus - Powerful. Affordable. Sign up > now. > http://mailplus.yahoo.com > ===== Jon Smirl jon...@ya... __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com |
|
From: Geert U. <ge...@li...> - 2003-01-10 19:45:14
|
On Fri, 10 Jan 2003, James Simmons wrote:
> > I think we still have several corner cases, such as TRUECOLOR with bpp
> > <= 8, I'm not sure if that works.
>
> The matorx millenium has such a mode. So such things do exist.
>
> > - if (image->depth == 1) {
> > + if (image->depth == 0) {
>
> P.S
>
> I'm just not to crazy about the depth equal zero thing. I just pitcure
> developers having a hard time with it.
Monochrome color expansion just works differently: it expands the zeroes and
ones in a bitmap based on fg_color and bg_color, while image drawing draws an
image containing colormap indices to the frame buffer.
Do you have a better suggestion?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: James S. <jsi...@in...> - 2003-01-10 19:44:06
|
> > Yes. Hardware rotation shouldn't also not effect the way accel > > operatations are done. > > The main difference is if the hardware supports rotation, fbcon will > present it with "normal" data. With the generic implementation, fbcon > will present the driver with rotated data. > > So we need a driver capabilities field either in fb_info or > fb_fix_screeninfo. We can just test if the rotation hook exist for the fbdev driver. No hook then use generic code in fbcon. Also we have a angle field in var so we can see if the user wants the data rotated. > Not really. We can dynamically rotate the fontdata using the default > display->fontdata into another buffer. I believe I have functions that > do that in the patch I submitted. (Sorry, I lost it when one of my > drives crashed :-(. I have that patch. It just has to be updated to the latest changes. |
|
From: Benjamin H. <be...@ke...> - 2003-01-10 19:43:13
|
Hi ! When setting a mode on an LCD display that is not exactly the native mode of that display, we can, on some chips, setup a scaler. However, most of the time, we have 2 difference choices for setting up this scaler: It can preserve or not preserve the aspect ratio. A typical example is the titnium powerbook's 1152x768 mode. If I set it to 1024x768, I can get either horizontal scaling (not preserving aspect ratio) or no scaling with black bars on left & right (preserving aspect ratio). While in most case you actually want to preserve the aspect ratio, it would still I beleive make sense to let the user choose it. Could we define one of the reserved fields in fb_var_screeninfo as beeing a "flags" field for such things ? There are a couple of other things that we may want to stuff into such a bitfield later, I'd suggest reserving one 32 bits field for such flags. Ben. -- Benjamin Herrenschmidt <be...@ke...> |
|
From: Geert U. <ge...@li...> - 2003-01-10 19:42:47
|
On Fri, 10 Jan 2003, James Simmons wrote:
> > Secondly, indexing the cmap instead of the pseudo_palette means that
> > cfb_imageblit has to know the native framebuffer format.
>
> No indexing the cmap. Instead call fb_set_cmap before we call
> xxxfb_imageblit. Personally I think we should call fb_set_cmap always.
>
> > I would rather have everything refer to
> > the pseudopalette, regardless of the visual format. This will be better
> > especially for some of the corner cases, like monochrome cards with
> > bits_per_pixel = 8.
>
> It works pretty good for for any pack pixel type modes. Now for planar
> cards this isn't the case. Ideally struct fb_cmap should have contained
What do you mean? I don't see a problem for planar modes. A pixel is still a
value of size n bits, it's just that the n bits are not located next to each
other, but spread across multiple words. planar_imageblit() will take care of
converting from chunky to planar mode.
BTW, I do have a working amifb now (it's in Linux/m68k CVS), but the
imageblit() needs more optimizations.
> a
>
> unsigned long pixel;
>
> field. Like X does. It does not and changing that would break things :-(
And let the fbdev driver fill in the pixel values, based on the fb_cmap?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: James S. <jsi...@in...> - 2003-01-10 19:41:13
|
> > I thought about this. Originally I did have this function but removed it.
> > WHat do you think Geert?
>
> Yes, that's OK.
>
> But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> fb_image.data as well. IIRC, all (most?) current clipping implementations
> modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.
Good point. Of course we could ignore pieces of data in that image instead
of altering the data. Altering the entire data would be expensive.
> > > The other option (which I don't like) is just to check the passed
> > > fb_var_screeninfo in the put_var ioctl against the current console
> > > window size. But this is not foolproof as we will not be sure of the
> > > resulting window size _after_ the fb_set_var() call.
> >
> > Yuck!!! The other way is better.
>
> Well, in between the calls to fb_ops.fb_check_var() and fb_ops.set_par() you
> can still perform that check. But it's indeed ugly.
Altering to the framebuffer via /dev/fb that would effect the tty should
not remain after the final close of /dev/fb. Instead the console should
reset to its previous state before we first opened /dev/fb.
|
|
From: Jon S. <jon...@ya...> - 2003-01-10 19:40:56
|
--- James Simmons <jsi...@in...> wrote: > So it is a matter of time before they will release > this info. > If you can get me the info, I will do the work. I own both Rage and Radeon cards so I can do some testing. I'll also add DDC support if they'll give me that info. I spent last night disassembling their ROMs. The reset procedure is not too difficult. But I would much rather do it with support from ATI documentation. It is easy to misinterpret a disassembly. Do you have a personal contact there? Maybe they can be convinced to publicly release documentation for their older products. I'm sure NVidia doesn't care how the Rage chip works any more. It would make a good PR release about ATI being a community citizen. It would also free their developer relations group from hassling with open source developers on older cards. ===== Jon Smirl jon...@ya... __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com |
|
From: James S. <jsi...@in...> - 2003-01-10 19:32:47
|
> I doubt if the procedure for resetting the board is > considered a trade secret. The problem is in getting > ATIs attention long enough to tell how to do it. It > may be as simple as poking an output port with a > special value. Hopefully someone with a manual can > tell me. Actually they are funny about it. We have asked before for this info. The good news is they are starting to lighten up about that. I have code to boot old Mach 64 cards without a BIOS. I haven't had time to fix it tho. So it is a matter of time before they will release this info. |
|
From: James S. <jsi...@in...> - 2003-01-10 19:28:36
|
> I think we still have several corner cases, such as TRUECOLOR with bpp
> <= 8, I'm not sure if that works.
The matorx millenium has such a mode. So such things do exist.
> - if (image->depth == 1) {
> + if (image->depth == 0) {
P.S
I'm just not to crazy about the depth equal zero thing. I just pitcure
developers having a hard time with it.
|
|
From: James S. <jsi...@in...> - 2003-01-10 19:24:17
|
> I've thought of that also, packing the data according to the pixel depth. Actually I was think more along the image depth. The largest the penguin logo gets is 224 colors. Meaning the largest image.depth is 8 bits per pixel. I do agree it is messy to pack the logo data. So for say the 16 color logo (4 bpp) putting two pixels worth of data into each byte and then seperating it out would be time consuming. The only reason I was thinking this way is because of userland using the cursor means imageblit is visible to userland. > a. Prepare logo data so each pixel of data is in directcolor format (if > we will use the cmap), so depth corresponds to framebuffer depth, and > data is packed. The depth doesn't have to be the same as the framebuffer depth. The logo data is in terms of color map indices. I did think in terms of packed data tho. > d. Get each color component from the cmap data. > > e. Recreate pixel data based on var.[color].offset and > var.[color].length. Yuck no. Doing a fb_set_cmap should handle that before we call xxxfb_imageblit. Then xxxfb_imageblit only has to take the data in the logo data as indices of the color map. Of > f. Write the pixel data in packed form to the framebuffer. > Whereas, with the current approach: > > a. Prepare logo data such that each pixel corresponds to one byte. > > b. Pass the structure to cfb_imageblit. > > c. Read color information from pseudopalette if directcolor/truecolor. > > d. Write the pixel data in packed form to the framebuffer. I was think the same way except for the idea of more than one color indices per byte for less than 8 bpp modes. > Secondly, indexing the cmap instead of the pseudo_palette means that > cfb_imageblit has to know the native framebuffer format. No indexing the cmap. Instead call fb_set_cmap before we call xxxfb_imageblit. Personally I think we should call fb_set_cmap always. > I would rather have everything refer to > the pseudopalette, regardless of the visual format. This will be better > especially for some of the corner cases, like monochrome cards with > bits_per_pixel = 8. It works pretty good for for any pack pixel type modes. Now for planar cards this isn't the case. Ideally struct fb_cmap should have contained a unsigned long pixel; field. Like X does. It does not and changing that would break things :-( |
|
From: James S. <jsi...@in...> - 2003-01-10 18:48:39
|
> Hopefully, exotics such as this will not export their visuals as > truecolor or static pseudocolor because fb_set_cmap() will not be > called. Otherwise, we'll just make it mandatory to call fb_set_cmap() > for all visual modes requiring linux_logo. Personally I think the best solution is to always call fb_set_cmap. Also the other issue is the 256 versus 16 length of pseudo_palette. We might have to have pseudo_palette either at the highest value, usually 256, or make pseudo_palette dynamic and change its size if the color depth changes. > I believe the cursor inversion value is unused anymore(?), since > fbcon_revc is gone. It has been replaced by the new cursor API which > allows the driver more intimate handling of the cursor. Correct. We don't need the 17th value now :-) |
|
From: James S. <jsi...@in...> - 2003-01-10 18:38:16
|
> Bummer, /me should read the code more thoroughfully...
>
> Perhaps renaming `{saved_,}palette' to `{saved_,}pseudo_palette' would make
> this clearer...
I renamed it.
|
|
From: James S. <jsi...@in...> - 2003-01-10 18:19:36
|
> Here's an improved GTF implementation. I was a bit delayed because I > was trying to find a way to do square roots without using floating > point. The diff is against linux-2.5.54 + your latest fbdev.diff. Applied. > but is more or less usable. Tested with i810fb and rivafb. (For rivafb, > I have to use a hacked version. The latest one does not work for the > riva128). What hack did you do? That is based on the latest riva driver from 2.4.2X. > BTW, I downloaded the source code of read-edid, and it seems that the > following monitor limits are parsable from the EDID block: HorizSync, > VertRefresh, DotClock, and GTF capability. We may change info->monspecs > to match that. Also, the EDID contains a list of supported modes, but > there's only 4 of them(?). I figured monspec would have to be improved. I'm looking into the EDID info right now. I'm also looking at read-edid. Next I need to figure out how to use i2c to get this info. |
|
From: Antonino D. <ad...@po...> - 2003-01-10 15:49:28
|
On Mon, 2003-01-06 at 22:54, Antonino Daplas wrote:
> So, what's needed is a function that calculates timing parameters which
> is generic enough to work with the most common monitors. One solution
> is to use VESA's GTF (Generalized Timing Formula). Attached is a patch
> that implements the formula.
>
James,
Attached is a diff against linux-2.5.54 + your latest fbdev.diff.
Hopefully it's the final installment for the GTF implementation.
The fb_get_mode() function checks for a bit in 'flags' (FB_IGNOREMON) so
it will generate GTF timings regardless of the validity of
info->monspecs. This way, drivers can still use GTF even if they don't
have the operational limits of the monitor. They'll just decide what is
a practical safe limit.
This particular code snippet can be inserted in xxxfb_check_var() after
rounding off var->xres and var->yres.
...
if (fb_validate_mode(var, info)) {
if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
!info->monspecs.dclkmax ||
info->monspecs.hfmax < info->monspecs.hfmin ||
info->monspecs.vfmax < info->monspecs.vfmin ||
info->monspecs.dclkmax < info->monspecs.dclkmin)
fb_get_mode(FB_IGNOREMON | FB_VSYNCTIMINGS, 60, var, info);
else
if (fb_get_mode(FB_MAXTIMINGS, 0, var, info))
return -EINVAL;
}
...
With the above, the driver will switch to a 60Hz refresh rate timings
(safe even for low-end monitors up to 1024x768) if monspecs is invalid.
Other changes: added a few more fields to fb_info.monspecs.
Tony
diff -Naur linux-2.5.54/drivers/video/fbmon.c linux/drivers/video/fbmon.c
--- linux-2.5.54/drivers/video/fbmon.c 2003-01-10 15:17:22.000000000 +0000
+++ linux/drivers/video/fbmon.c 2003-01-10 15:10:44.000000000 +0000
@@ -511,6 +511,9 @@
* refresh rate. Otherwise, it will calculate timings based on
* the flag and accompanying value.
*
+ * If FB_IGNOREMON bit is set in @flags, monitor specs will be
+ * ignored and @var will be filled with the calculated timings.
+ *
* All calculations are based on the VESA GTF Spreadsheet
* available at VESA's public ftp (http://www.vesa.org).
*
@@ -527,22 +530,27 @@
{
struct __fb_timings timings;
u32 interlace = 1, dscan = 1;
- u32 hfmin, hfmax, vfmin, vfmax;
+ u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
/*
* If monspecs are invalid, use values that are enough
* for 640x480@60
*/
- if ((!info->monspecs.hfmax && !info->monspecs.vfmax) ||
+ if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
+ !info->monspecs.dclkmax ||
info->monspecs.hfmax < info->monspecs.hfmin ||
- info->monspecs.vfmax < info->monspecs.vfmin) {
+ info->monspecs.vfmax < info->monspecs.vfmin ||
+ info->monspecs.dclkmax < info->monspecs.dclkmin) {
hfmin = 29000; hfmax = 30000;
vfmin = 60; vfmax = 60;
+ dclkmin = 0; dclkmax = 25000000;
} else {
hfmin = info->monspecs.hfmin;
hfmax = info->monspecs.hfmax;
vfmin = info->monspecs.vfmin;
vfmax = info->monspecs.vfmax;
+ dclkmin = info->monspecs.dclkmin;
+ dclkmax = info->monspecs.dclkmax;
}
memset(&timings, 0, sizeof(struct __fb_timings));
@@ -557,8 +565,8 @@
dscan = 2;
}
- switch (flags) {
- case 0: /* maximize refresh rate */
+ switch (flags & ~FB_IGNOREMON) {
+ case FB_MAXTIMINGS: /* maximize refresh rate */
timings.hfreq = hfmax;
fb_timings_hfreq(&timings);
if (timings.vfreq > vfmax) {
@@ -566,15 +574,15 @@
fb_timings_vfreq(&timings);
}
break;
- case 1: /* vrefresh driven */
+ case FB_VSYNCTIMINGS: /* vrefresh driven */
timings.vfreq = val;
fb_timings_vfreq(&timings);
break;
- case 2: /* hsync driven */
+ case FB_HSYNCTIMINGS: /* hsync driven */
timings.hfreq = val;
fb_timings_hfreq(&timings);
break;
- case 3: /* pixelclock driven */
+ case FB_DCLKTIMINGS: /* pixelclock driven */
timings.dclk = PICOS2KHZ(val) * 1000;
fb_timings_dclk(&timings);
break;
@@ -583,11 +591,12 @@
}
- if (timings.vfreq < vfmin || timings.vfreq > vfmax ||
- timings.hfreq < hfmin || timings.hfreq > hfmax)
+ if (!(flags & FB_IGNOREMON) &&
+ (timings.vfreq < vfmin || timings.vfreq > vfmax ||
+ timings.hfreq < hfmin || timings.hfreq > hfmax ||
+ timings.dclk < dclkmin || timings.dclk > dclkmax))
return -EINVAL;
-
var->pixclock = KHZ2PICOS(timings.dclk/1000);
var->hsync_len = (timings.htotal * 8)/100;
var->right_margin = (timings.hblank/2) - var->hsync_len;
@@ -616,22 +625,27 @@
int fb_validate_mode(struct fb_var_screeninfo *var, struct fb_info *info)
{
u32 hfreq, vfreq, htotal, vtotal, pixclock;
- u32 hfmin, hfmax, vfmin, vfmax;
+ u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
/*
* If monspecs are invalid, use values that are enough
* for 640x480@60
*/
- if ((!info->monspecs.hfmax && !info->monspecs.vfmax) ||
+ if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
+ !info->monspecs.dclkmax ||
info->monspecs.hfmax < info->monspecs.hfmin ||
- info->monspecs.vfmax < info->monspecs.vfmin) {
+ info->monspecs.vfmax < info->monspecs.vfmin ||
+ info->monspecs.dclkmax < info->monspecs.dclkmin) {
hfmin = 29000; hfmax = 30000;
vfmin = 60; vfmax = 60;
+ dclkmin = 0; dclkmax = 25000000;
} else {
hfmin = info->monspecs.hfmin;
hfmax = info->monspecs.hfmax;
vfmin = info->monspecs.vfmin;
vfmax = info->monspecs.vfmax;
+ dclkmin = info->monspecs.dclkmin;
+ dclkmax = info->monspecs.dclkmax;
}
if (!var->pixclock)
diff -Naur linux-2.5.54/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.5.54/include/linux/fb.h 2003-01-10 15:17:37.000000000 +0000
+++ linux/include/linux/fb.h 2003-01-10 15:19:56.000000000 +0000
@@ -240,6 +240,9 @@
__u32 hfmax; /* hfreq upper limit (Hz) */
__u16 vfmin; /* vfreq lower limit (Hz) */
__u16 vfmax; /* vfreq upper limit (Hz) */
+ __u32 dclkmin; /* pixelclock lower limit (Hz) */
+ __u32 dclkmax; /* pixelclock upper limit (Hz) */
+ unsigned gtf : 1; /* supports GTF */
unsigned dpms : 1; /* supports DPMS */
};
@@ -465,6 +468,12 @@
extern int num_registered_fb;
/* drivers/video/fbmon.c */
+#define FB_MAXTIMINGS 0
+#define FB_VSYNCTIMINGS 1
+#define FB_HSYNCTIMINGS 2
+#define FB_DCLKTIMINGS 3
+#define FB_IGNOREMON 0x100
+
extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
const struct fb_info *fb_info);
extern int fbmon_dpms(const struct fb_info *fb_info);
|
|
From: Antonino D. <ad...@po...> - 2003-01-10 14:47:47
|
On Fri, 2003-01-10 at 02:09, James Simmons wrote:
> >
> > So maybe if we can rename fb_putcs() to fb_tileblit(), fb_setfont() to
> > fb_loadtiles(), struct fb_chars to struct fb_tilemap and struct
> > fb_fontdata to struct fb_tiledata, maybe it will be more acceptable?
> >
> > It can be even be expanded by including fb_tiledata.depth
> > fb_tiledata.cmap so we can support multi-colored tiled blitting.
>
> This I have no problem with. I'm willing to accept this. As long as data
> from the console layer is not touched. As for loadtiles one thing I like
> to address is memory allocation. It probable is good idea to do things
> like place the tile data in buffers allocated by pci_alloc_consistent.
> The other fear is it will only support so many tiles.
>
Hmm, so you're willing to accept this... okay, attached is another
patch, made it a bit cleaner so none of the console data will be ever
touched. Also expanded it so tile blitting has an equivalent
counterpart with classic blitting.
Thinking about it, I think tile blitting may one day become useful if
ever the console supports more than 16-colors. Imagine how expensive it
would be to draw 32-bit fonts using classic blitting.
Tried it with a few test hooks, works fine except for one thing: the
font is initially scrambled at boot, but became fixed later on. I don't
know how to fix that.
Tony
diff -Naur linux-2.5.54/drivers/video/console/fbcon.c linux/drivers/video/console/fbcon.c
--- linux-2.5.54/drivers/video/console/fbcon.c 2003-01-10 11:08:04.000000000 +0000
+++ linux/drivers/video/console/fbcon.c 2003-01-10 11:04:59.000000000 +0000
@@ -350,35 +350,91 @@
{
struct fb_info *info = p->fb_info;
struct vc_data *vc = p->conp;
- struct fb_copyarea area;
- area.sx = sx * vc->vc_font.width;
- area.sy = sy * vc->vc_font.height;
- area.dx = dx * vc->vc_font.width;
- area.dy = dy * vc->vc_font.height;
- area.height = height * vc->vc_font.height;
- area.width = width * vc->vc_font.width;
+ if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+ struct fb_tilecopy tilerect;
- info->fbops->fb_copyarea(info, &area);
+ tilerect.sx = sx;
+ tilerect.sy = sy;
+ tilerect.dx = dx;
+ tilerect.dy = dy;
+ tilerect.width = width;
+ tilerect.height = height;
+
+ info->tileops->fb_tilecopy(info, &tilerect);
+ } else {
+ struct fb_copyarea area;
+
+ area.sx = sx * vc->vc_font.width;
+ area.sy = sy * vc->vc_font.height;
+ area.dx = dx * vc->vc_font.width;
+ area.dy = dy * vc->vc_font.height;
+ area.height = height * vc->vc_font.height;
+ area.width = width * vc->vc_font.width;
+
+ info->fbops->fb_copyarea(info, &area);
+ }
}
void accel_clear(struct vc_data *vc, struct display *p, int sy,
int sx, int height, int width)
{
struct fb_info *info = p->fb_info;
- struct fb_fillrect region;
+ if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+ struct fb_tilefill tilerect;
- region.color = attr_bgcol_ec(p, vc);
- region.dx = sx * vc->vc_font.width;
- region.dy = sy * vc->vc_font.height;
- region.width = width * vc->vc_font.width;
- region.height = height * vc->vc_font.height;
- region.rop = ROP_COPY;
+ tilerect.dx = sx;
+ tilerect.dy = sy;
+ tilerect.width = width;
+ tilerect.height = height;
+ tilerect.fg_color = attr_fgcol_ec(p, vc);
+ tilerect.bg_color = attr_bgcol_ec(p, vc);
+ tilerect.idx = vc->vc_video_erase_char & p->charmask;
+ tilerect.rop = ROP_COPY;
- info->fbops->fb_fillrect(info, ®ion);
-}
+ info->tileops->fb_tilefill(info, &tilerect);
+ } else {
+ struct fb_fillrect region;
+
+ region.color = attr_bgcol_ec(p, vc);
+ region.dx = sx * vc->vc_font.width;
+ region.dy = sy * vc->vc_font.height;
+ region.width = width * vc->vc_font.width;
+ region.height = height * vc->vc_font.height;
+ region.rop = ROP_COPY;
+
+ info->fbops->fb_fillrect(info, ®ion);
+ }
+}
#define FB_PIXMAPSIZE 8192
+static void tile_putcs(struct vc_data *vc, struct display *p, u32 *tilemap,
+ const unsigned short *s, int count, int yy, int xx)
+{
+ struct fb_info *info = p->fb_info;
+ struct fb_tileblit tilerect;
+ int maxcnt = FB_PIXMAPSIZE/4, i, cnt;
+ u16 c = scr_readw(s);
+
+ tilerect.dx = xx;
+ tilerect.dy = yy;
+ tilerect.height = 1;
+ tilerect.fg_color = attr_fgcol(p, c);
+ tilerect.bg_color = attr_bgcol(p, c);
+ tilerect.data = tilemap;
+
+ while (count) {
+ cnt = (count > maxcnt) ? maxcnt : count;
+ tilerect.width = cnt;
+ for (i = 0; i < cnt; i++)
+ tilemap[i] = (u32) (scr_readw(s++) & p->charmask);
+
+ info->tileops->fb_tileblit(info, &tilerect);
+ tilerect.dx += cnt;
+ count -= cnt;
+ }
+}
+
void accel_putcs(struct vc_data *vc, struct display *p,
const unsigned short *s, int count, int yy, int xx)
{
@@ -390,6 +446,11 @@
u16 c = scr_readw(s);
static u8 pixmap[FB_PIXMAPSIZE];
+ if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+ tile_putcs(vc, p, (u32 *) pixmap, s, count, yy, xx);
+ return;
+ }
+
image.fg_color = attr_fgcol(p, c);
image.bg_color = attr_bgcol(p, c);
image.dx = xx * vc->vc_font.width;
@@ -452,6 +513,10 @@
unsigned int bs = info->var.yres - bh;
struct fb_fillrect region;
+ /* unneeded for tile blits */
+ if (info->caps && FB_CAPS_TILEBLIT && info->tileops)
+ return;
+
region.color = attr_bgcol_ec(p, vc);
region.rop = ROP_COPY;
@@ -1150,7 +1215,6 @@
struct fb_info *info = p->fb_info;
unsigned short charmask = p->charmask;
unsigned int width = ((vc->vc_font.width + 7) >> 3);
- struct fb_image image;
int redraw_cursor = 0;
if (!p->can_soft_blank && console_blanked)
@@ -1164,17 +1228,33 @@
redraw_cursor = 1;
}
- image.fg_color = attr_fgcol(p, c);
- image.bg_color = attr_bgcol(p, c);
- image.dx = xpos * vc->vc_font.width;
- image.dy = real_y(p, ypos) * vc->vc_font.height;
- image.width = vc->vc_font.width;
- image.height = vc->vc_font.height;
- image.depth = 1;
- image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
+ if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+ struct fb_tileblit tilerect;
+
+ u32 font = c & charmask;
+ tilerect.dx = xpos;
+ tilerect.dy = real_y(p, ypos);
+ tilerect.width = 1;
+ tilerect.height = 1;
+ tilerect.fg_color = attr_fgcol(p, c);
+ tilerect.bg_color = attr_bgcol(p, c);
+ tilerect.data = &font;
+
+ info->tileops->fb_tileblit(info, &tilerect);
+ } else {
+ struct fb_image image;
- info->fbops->fb_imageblit(info, &image);
+ image.fg_color = attr_fgcol(p, c);
+ image.bg_color = attr_bgcol(p, c);
+ image.dx = xpos * vc->vc_font.width;
+ image.dy = real_y(p, ypos) * vc->vc_font.height;
+ image.width = vc->vc_font.width;
+ image.height = vc->vc_font.height;
+ image.depth = 1;
+ image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
+ info->fbops->fb_imageblit(info, &image);
+ }
if (redraw_cursor)
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
@@ -1935,6 +2015,31 @@
scrollback_max = 0;
scrollback_current = 0;
+ if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+ struct fb_tiledata tile;
+ int err, cnt = FNTCHARCNT(p->fontdata);
+ int size = (vc->vc_font.height * vc->vc_font.width)/8 * cnt;
+ u8 *tiledata;
+
+ /*
+ * make sure we don't allow drivers to mangle
+ * console fontdata
+ */
+ tiledata = kmalloc(size, GFP_KERNEL);
+ if (tiledata == NULL)
+ return 0;
+ memcpy(tiledata, p->fontdata, size);
+ tile.tile.width = vc->vc_font.width;
+ tile.tile.height = vc->vc_font.height;
+ tile.tile.depth = 1;
+ tile.len = cnt;
+ tile.data = tiledata;
+ err = info->tileops->fb_loadtiles(info, &tile);
+ kfree(tiledata);
+
+ if (err) return 0;
+ }
+
info->currcon = unit;
fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
@@ -2152,6 +2257,27 @@
}
+ if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+ struct fb_tiledata tile;
+ int size = (vc->vc_font.height * vc->vc_font.width)/8 * cnt;
+ int err;
+ u8 *tiledata;
+
+ tiledata = kmalloc(size, GFP_KERNEL);
+ if (tiledata == NULL)
+ return 1;
+ memcpy(tiledata, p->fontdata, size);
+ tile.tile.width = vc->vc_font.width;
+ tile.tile.height = vc->vc_font.height;
+ tile.tile.depth = 1;
+ tile.len = cnt;
+ tile.data = tiledata;
+
+ err = info->tileops->fb_loadtiles(info, &tile);
+ kfree(tiledata);
+ if (err) return err;
+ }
+
if (resize) {
/* reset wrap/pan */
info->var.xoffset = info->var.yoffset = p->yscroll = 0;
diff -Naur linux-2.5.54/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.5.54/include/linux/fb.h 2003-01-10 11:08:19.000000000 +0000
+++ linux/include/linux/fb.h 2003-01-10 11:21:27.000000000 +0000
@@ -173,6 +173,10 @@
#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+/* Driver Capability */
+#define FB_CAPS_CLIPPING 1 /* hardware can do clipping */
+#define FB_CAPS_TILEBLIT 2 /* hardware can do tileblits */
+
#define PICOS2KHZ(a) (1000000000UL/(a))
#define KHZ2PICOS(a) (1000000000UL/(a))
@@ -377,6 +381,77 @@
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
};
+/*
+ * Tile Blitting Support
+ *
+ * In Tile Blitting, the basic unit is a Tile which is a bitmap with
+ * a predefined width and height, and optionally, other properties
+ * such as color depth, spacing, transparency, etc. For now, we'll
+ * just support width, height, and color depth.
+ *
+ * All operations are analogous to classic blitting operations which
+ * use pixels as the basic unit. Instead of pixels, it will use tiles,
+ * instead of info->pseudo_palette, it will use tiledata, etc.
+ */
+
+struct fb_tile {
+ __u32 width; /* tile width in pixels */
+ __u32 height; /* tile height in scanlines */
+ __u32 depth; /* pixel depth */
+};
+
+struct fb_tiledata {
+ struct fb_tile tile; /* tile properties */
+ __u32 len; /* number of tiles in the map */
+ __u8 *data; /* packed tile data */
+};
+
+struct fb_tileblit {
+ __u32 dx; /* destination x origin, in tiles */
+ __u32 dy; /* destination y origin, in tiles */
+ __u32 width; /* destination window width, in tiles */
+ __u32 height; /* destination window height, in tiles */
+ __u32 fg_color; /* fg_color if monochrome */
+ __u32 bg_color; /* bg_color if monochrome */
+ __u32 *data; /* tile map - array of indices to tiledata */
+};
+
+struct fb_tilecopy {
+ __u32 dx; /* destination window origin... */
+ __u32 dy; /* in tiles */
+ __u32 width; /* destination width, in tiles */
+ __u32 height; /* destination height, in tiles */
+ __u32 sx; /* source window origin ... */
+ __u32 sy; /* in tiles */
+};
+
+struct fb_tilefill {
+ __u32 dx; /* destination window origin ... */
+ __u32 dy; /* in tiles */
+ __u32 width; /* destination width in tiles */
+ __u32 height; /* destination height in tiles */
+ __u32 fg_color; /* fg_color if monochrome */
+ __u32 bg_color; /* bg_color if monochrome */
+ __u32 rop; /* rop operation */
+ __u32 idx; /* index to current tiledata */
+};
+
+struct fb_tileops {
+ /* upload tile data to driver and make it current... the driver
+ * must copy the contents of tiledata.data, not just the pointer to it */
+ int (*fb_loadtiles)(struct fb_info *info,
+ const struct fb_tiledata *tile);
+ /* blit tiles to destination from a tilemap */
+ void (*fb_tileblit)(struct fb_info *info,
+ const struct fb_tileblit *tilemap);
+ /* copy tiles from one region of fb memory to another */
+ void (*fb_tilecopy)(struct fb_info *info, const struct fb_tilecopy *area);
+ /* fill a region of fb memory with a tile */
+ void (*fb_tilefill)(struct fb_info *info,
+ const struct fb_tilefill *region);
+ /* If driver is to support tile blitting, all hooks above are required */
+};
+
struct fb_info {
kdev_t node;
int flags;
@@ -388,6 +463,7 @@
struct fb_cursor cursor; /* Current cursor */
struct fb_cmap cmap; /* Current cmap */
struct fb_ops *fbops;
+ struct fb_tileops *tileops /* Tile blitting */
char *screen_base; /* Virtual address */
struct vc_data *display_fg; /* Console visible on this display */
int currcon; /* Current VC. */
|
|
From: Geert U. <ge...@li...> - 2003-01-10 14:11:57
|
On 10 Jan 2003, Antonino Daplas wrote:
> For putcs and putc, I just made it mandatory that when one character is
> to be out of bounds, it just won't get drawn. A cleaner implementation
> is, of course, to clip the destination window + the passed bitmap.
Except for the geek value, why would it be cleaner to draw half of a character
near the border?
> Do we need to clip the fb_set_logo() too?
I don't think so. The current code already draws only the number of logos that
really fit on the screen. Unless you want to see half penguins as well :-)
> The patch may be a bit difficult to swallow because it is pretty much
> invasive and not so clean :-(, so it's okay if you don't take it.
> But it has the advantage of clipping the coordinates for hardware that
> does not support clipping (like the i810fb). For hardware that does
> support clipping, or wants to implement its own clipping code, we require
> a 'caps' (capabilities) field in fb_info or fb_fix_screeninfo. This is
> checked first and if set, the default clipping code is bypassed.
I prefer fb_info, since user space doesn't need to know.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: Antonino D. <ad...@po...> - 2003-01-10 14:06:13
|
On Fri, 2003-01-10 at 05:46, Geert Uytterhoeven wrote:
> On Thu, 9 Jan 2003, James Simmons wrote:
> > > So perhaps, a function something like this:
> > >
> > > void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);
> > >
> > > This should not be difficult to implement, and I'll code it if everyone
> > > agrees.
> >
> > I thought about this. Originally I did have this function but removed it.
> > WHat do you think Geert?
>
> Yes, that's OK.
>
> But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> fb_image.data as well. IIRC, all (most?) current clipping implementations
> modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.
>
> > > The other option (which I don't like) is just to check the passed
> > > fb_var_screeninfo in the put_var ioctl against the current console
> > > window size. But this is not foolproof as we will not be sure of the
> > > resulting window size _after_ the fb_set_var() call.
> >
> > Yuck!!! The other way is better.
>
> Well, in between the calls to fb_ops.fb_check_var() and fb_ops.set_par() you
> can still perform that check. But it's indeed ugly.
>
Geert, James
I've attached a patch that implements clipping in the fbcon layer using
2 generic clipping functions:
fb_clip_region() - one area to clip; and
fb_clip_region2() - two areas to clip (source and destination) as in
copyarea()
The above functions use this:
struct fb_region {
__u32 dx;
__u32 dy;
__u32 width;
__u32 height;
};
which is just a subset of fb_{image,copyarea,fillrect}. Good thing that
you arranged those fields in the right order :-).
fb_clip_region() is a standard clipping implementation, whereas
fb_clip_region2() is a bit trickier because it has to clip _both_ the
source and destination against each other. Most of 2 operand clipping
operations always assume that the source area need not be clipped.
For putcs and putc, I just made it mandatory that when one character is
to be out of bounds, it just won't get drawn. A cleaner implementation
is, of course, to clip the destination window + the passed bitmap.
For accel_cursor(), if it's going out of bounds, I place it at
screenpos(0,0) and hide it. Hopefully no one notices :-)
Do we need to clip the fb_set_logo() too?
I've also modified the cfb_{fillrect,copyarea,imageblit}: removed
clipping code and so it does not modify the passed parameters.
The patch may be a bit difficult to swallow because it is pretty much
invasive and not so clean :-(, so it's okay if you don't take it.
But it has the advantage of clipping the coordinates for hardware that
does not support clipping (like the i810fb). For hardware that does
support clipping, or wants to implement its own clipping code, we require
a 'caps' (capabilities) field in fb_info or fb_fix_screeninfo. This is
checked first and if set, the default clipping code is bypassed.
Here's how it currently works in my system:
1. reduce xres_virtual - works as expected, the tail end of the chars
are truncated.
2. reduce yres_virtual - works as expected but display is useless as the
screen is located deep down towards the end of yres_virtual.
In all cases, the screen can be restored when switching from another
console and back.
Tony
diff -Naur linux-2.5.54/drivers/video/cfbcopyarea.c linux/drivers/video/cfbcopyarea.c
--- linux-2.5.54/drivers/video/cfbcopyarea.c 2003-01-09 13:58:14.000000000 +0000
+++ linux/drivers/video/cfbcopyarea.c 2003-01-09 13:57:43.000000000 +0000
@@ -321,7 +321,6 @@
void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
{
- int x2, y2, old_dx, old_dy, vxres, vyres;
unsigned long next_line = p->fix.line_length;
int dst_idx = 0, src_idx = 0, rev_copy = 0;
unsigned long *dst = NULL, *src = NULL;
@@ -330,40 +329,6 @@
if (!p->fbops->fb_rotate && p->var.rotate) {
}
- vxres = p->var.xres_virtual;
- vyres = p->var.yres_virtual;
-
- if (area->dx > vxres || area->sx > vxres ||
- area->dy > vyres || area->sy > vyres)
- return;
-
- /* clip the destination */
- old_dx = area->dx;
- old_dy = area->dy;
-
- /*
- * We could use hardware clipping but on many cards you get around
- * hardware clipping by writing to framebuffer directly.
- */
- x2 = area->dx + area->width;
- y2 = area->dy + area->height;
- area->dx = area->dx > 0 ? area->dx : 0;
- area->dy = area->dy > 0 ? area->dy : 0;
- x2 = x2 < vxres ? x2 : vxres;
- y2 = y2 < vyres ? y2 : vyres;
- area->width = x2 - area->dx;
- area->height = y2 - area->dy;
-
- /* update sx1,sy1 */
- area->sx += (area->dx - old_dx);
- area->sy += (area->dy - old_dy);
-
- /* the source must be completely inside the virtual screen */
- if (area->sx < 0 || area->sy < 0 ||
- (area->sx + area->width) > vxres ||
- (area->sy + area->height) > vyres)
- return;
-
if (area->dy > area->sy || (area->dy == area->sy && area->dx > area->sx)) {
area->dy += area->height;
area->sy += area->height;
diff -Naur linux-2.5.54/drivers/video/cfbfillrect.c linux/drivers/video/cfbfillrect.c
--- linux-2.5.54/drivers/video/cfbfillrect.c 2003-01-09 13:58:10.000000000 +0000
+++ linux/drivers/video/cfbfillrect.c 2003-01-09 13:57:44.000000000 +0000
@@ -361,7 +361,6 @@
void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
{
unsigned long height, fg;
- unsigned long x2, y2, vxres, vyres;
unsigned long *dst;
int dst_idx, left;
u32 bpp = p->var.bits_per_pixel;
@@ -370,21 +369,7 @@
if (!p->fbops->fb_rotate && p->var.rotate) {
}
- vxres = p->var.xres_virtual;
- vyres = p->var.yres_virtual;
-
- if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)
- return;
-
- /* We could use hardware clipping but on many cards you get around
- * hardware clipping by writing to framebuffer directly. */
-
- x2 = rect->dx + rect->width;
- y2 = rect->dy + rect->height;
- x2 = x2 < vxres ? x2 : vxres;
- y2 = y2 < vyres ? y2 : vyres;
- rect->width = x2 - rect->dx;
- height = y2 - rect->dy;
+ height = rect->height;
if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
p->fix.visual == FB_VISUAL_DIRECTCOLOR )
diff -Naur linux-2.5.54/drivers/video/cfbimgblt.c linux/drivers/video/cfbimgblt.c
--- linux-2.5.54/drivers/video/cfbimgblt.c 2003-01-09 13:58:19.000000000 +0000
+++ linux/drivers/video/cfbimgblt.c 2003-01-09 15:52:14.000000000 +0000
@@ -88,11 +88,13 @@
#if defined (__BIG_ENDIAN)
#define LEFT_POS(bpp) (BITS_PER_LONG - bpp)
+#define LEFT_POS32(bpp) (32 - bpp)
#define NEXT_POS(pos, bpp) ((pos) -= (bpp))
#define SHIFT_HIGH(val, bits) ((val) >> (bits))
#define SHIFT_LOW(val, bits) ((val) << (bits))
#else
#define LEFT_POS(bpp) (0)
+#define LEFT_POS32(bpp) (0)
#define NEXT_POS(pos, bpp) ((pos) += (bpp))
#define SHIFT_HIGH(val, bits) ((val) << (bits))
#define SHIFT_LOW(val, bits) ((val) >> (bits))
@@ -224,25 +226,25 @@
}
static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1,
- unsigned long fgcolor, unsigned long bgcolor)
+ u32 fgcolor, u32 bgcolor)
{
int i, j, k, l = 8, n;
- unsigned long bit_mask, end_mask, eorx;
- unsigned long fgx = fgcolor, bgx = bgcolor, pad, bpp = p->var.bits_per_pixel;
- unsigned long tmp = (1 << bpp) - 1;
- unsigned long ppw = BITS_PER_LONG/bpp, ppos;
- unsigned long *dst;
+ u32 bit_mask, end_mask, eorx;
+ u32 fgx = fgcolor, bgx = bgcolor, pad, bpp = p->var.bits_per_pixel;
+ u32 tmp = (1 << bpp) - 1;
+ u32 ppw = 32/bpp, ppos;
+ u32 *dst;
u32 *tab = NULL;
char *src = image->data;
- switch (ppw) {
- case 4:
+ switch (bpp) {
+ case 8:
tab = cfb_tab8;
break;
- case 2:
+ case 16:
tab = cfb_tab16;
break;
- case 1:
+ case 32:
tab = cfb_tab32;
break;
}
@@ -264,17 +266,17 @@
k = image->width/ppw;
for (i = image->height; i--; ) {
- dst = (unsigned long *) dst1;
+ dst = (u32 *) dst1;
for (j = k; j--; ) {
l -= ppw;
end_mask = tab[(*src >> l) & bit_mask];
- FB_WRITEL((end_mask & eorx)^bgx, dst++);
+ fb_writel((end_mask & eorx)^bgx, dst++);
if (!l) { l = 8; src++; }
}
if (n) {
end_mask = 0;
- ppos = LEFT_POS(bpp);
+ ppos = LEFT_POS32(bpp);
for (j = n; j > 0; j--) {
l--;
if (*src & (1 << l))
@@ -282,7 +284,7 @@
NEXT_POS(ppos, bpp);
if (!l) { l = 8; src++; }
}
- FB_WRITEL((end_mask & eorx)^bgx, dst++);
+ fb_writel((end_mask & eorx)^bgx, dst++);
}
l -= pad;
dst1 += p->fix.line_length;
@@ -291,30 +293,10 @@
void cfb_imageblit(struct fb_info *p, struct fb_image *image)
{
- int x2, y2, vxres, vyres;
unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
u8 *dst1;
- vxres = p->var.xres_virtual;
- vyres = p->var.yres_virtual;
- /*
- * We could use hardware clipping but on many cards you get around hardware
- * clipping by writing to framebuffer directly like we are doing here.
- */
- if (image->dx > vxres ||
- image->dy > vyres)
- return;
-
- x2 = image->dx + image->width;
- y2 = image->dy + image->height;
- image->dx = image->dx > 0 ? image->dx : 0;
- image->dy = image->dy > 0 ? image->dy : 0;
- x2 = x2 < vxres ? x2 : vxres;
- y2 = y2 < vyres ? y2 : vyres;
- image->width = x2 - image->dx;
- image->height = y2 - image->dy;
-
bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
start_index = bitstart & (BITS_PER_LONG - 1);
pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
@@ -337,7 +319,8 @@
bpp >= 8 && bpp <= 32 && (image->width & 7) == 0)
fast_imageblit(image, p, dst1, fgcolor, bgcolor);
else
- slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index);
+ slow_imageblit(image, p, dst1, (u32) fgcolor, (u32) bgcolor,
+ start_index, pitch_index);
}
else if (image->depth == bpp)
color_imageblit(image, p, dst1, start_index, pitch_index);
diff -Naur linux-2.5.54/drivers/video/console/fbcon.c linux/drivers/video/console/fbcon.c
--- linux-2.5.54/drivers/video/console/fbcon.c 2003-01-09 13:52:34.000000000 +0000
+++ linux/drivers/video/console/fbcon.c 2003-01-10 02:50:37.000000000 +0000
@@ -351,6 +351,7 @@
struct fb_info *info = p->fb_info;
struct vc_data *vc = p->conp;
struct fb_copyarea area;
+ struct fb_region clip, s_region, d_region;
area.sx = sx * vc->vc_font.width;
area.sy = sy * vc->vc_font.height;
@@ -359,6 +360,33 @@
area.height = height * vc->vc_font.height;
area.width = width * vc->vc_font.width;
+ if (!(info->caps & FB_CAPS_CLIPPING) &&
+ (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+ vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+ clip.dx = clip.dy = 0;
+ clip.width = info->var.xres_virtual;
+ clip.height = info->var.yres_virtual;
+
+ s_region.dx = area.sx;
+ s_region.dy = area.sy;
+ d_region.dx = area.dx;
+ d_region.dy = area.dy;
+ s_region.width = d_region.width = area.width;
+ s_region.height = d_region.height = area.height;
+
+ fb_clip_region2(&d_region, &s_region, &clip);
+
+ if (!d_region.width || !d_region.height)
+ return;
+
+ area.dx = d_region.dx;
+ area.dy = d_region.dy;
+ area.sx = s_region.dx;
+ area.sy = s_region.dy;
+ area.width = d_region.width;
+ area.height = d_region.height;
+ }
+
info->fbops->fb_copyarea(info, &area);
}
@@ -367,6 +395,7 @@
{
struct fb_info *info = p->fb_info;
struct fb_fillrect region;
+ struct fb_region clip;
region.color = attr_bgcol_ec(p, vc);
region.dx = sx * vc->vc_font.width;
@@ -375,9 +404,36 @@
region.height = height * vc->vc_font.height;
region.rop = ROP_COPY;
+ if (!(info->caps & FB_CAPS_CLIPPING) &&
+ (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+ vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+ clip.dx = clip.dy = 0;
+ clip.width = info->var.xres_virtual;
+ clip.height = info->var.yres_virtual;
+ fb_clip_region((struct fb_region *) ®ion, &clip);
+ if (!region.width || !region.height)
+ return;
+ }
+
info->fbops->fb_fillrect(info, ®ion);
}
+static int test_clip(struct fb_region *clip,
+ struct fb_region *src)
+{
+ struct fb_region region = *src;
+
+ fb_clip_region(®ion, clip);
+
+ if (region.dx != src->dx ||
+ region.dy != src->dy ||
+ region.width != src->width ||
+ region.height != src->height)
+ return 1;
+
+ return 0;
+}
+
#define FB_PIXMAPSIZE 8192
void accel_putcs(struct vc_data *vc, struct display *p,
const unsigned short *s, int count, int yy, int xx)
@@ -386,7 +442,9 @@
unsigned short charmask = p->charmask;
unsigned int width = ((vc->vc_font.width + 7)/8);
unsigned int cellsize = vc->vc_font.height * width;
+ unsigned int do_clip = 0;
struct fb_image image;
+ struct fb_region clip;
u16 c = scr_readw(s);
static u8 pixmap[FB_PIXMAPSIZE];
@@ -397,7 +455,26 @@
image.height = vc->vc_font.height;
image.depth = 1;
- if (!(vc->vc_font.width & 7)) {
+ if (!(info->caps & FB_CAPS_CLIPPING) &&
+ (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+ vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+ clip.dx = clip.dy = 0;
+ clip.width = info->var.xres_virtual;
+ clip.height = info->var.yres_virtual;
+ do_clip = 1;
+ /* we do some cheating here... If the bitmap will
+ * be clipped, we just pass it to the slower method
+ * of 1 imageblit per character.
+ */
+ if (!(vc->vc_font.width & 7)) {
+ struct fb_region *region = (struct fb_region *) ℑ
+
+ image.width = count * vc->vc_font.width;
+ do_clip = (test_clip(&clip, region)) ? 2 : do_clip;
+ }
+ }
+
+ if (!(vc->vc_font.width & 7) && do_clip != 2) {
unsigned int pitch, cnt, i, j, k;
unsigned int maxcnt = FB_PIXMAPSIZE/(vc->vc_font.height * width);
char *src, *dst, *dst0;
@@ -429,11 +506,14 @@
count -= cnt;
}
} else {
+ struct fb_region *region = (struct fb_region *) ℑ
image.width = vc->vc_font.width;
while (count--) {
image.data = p->fontdata +
(scr_readw(s++) & charmask) *
vc->vc_font.height * width;
+ if (do_clip && test_clip(&clip, region))
+ return;
info->fbops->fb_imageblit(info, &image);
image.dx += vc->vc_font.width;
}
@@ -450,16 +530,32 @@
unsigned int bh = info->var.yres % ch;
unsigned int rs = info->var.xres - rw;
unsigned int bs = info->var.yres - bh;
+ unsigned int do_clip = 0;
struct fb_fillrect region;
+ struct fb_region clip;
region.color = attr_bgcol_ec(p, vc);
region.rop = ROP_COPY;
+ if (!(info->caps & FB_CAPS_CLIPPING) &&
+ (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+ vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+ clip.dx = clip.dy = 0;
+ clip.width = info->var.xres_virtual;
+ clip.height = info->var.yres_virtual;
+ do_clip = 1;
+ }
+
if (rw & !bottom_only) {
region.dx = info->var.xoffset + rs;
region.dy = 0;
region.width = rw;
region.height = info->var.yres_virtual;
+ if (do_clip) {
+ fb_clip_region((struct fb_region *) ®ion, &clip);
+ if (!region.width || !region.height)
+ return;
+ }
info->fbops->fb_fillrect(info, ®ion);
}
@@ -468,6 +564,11 @@
region.dy = info->var.yoffset + bs;
region.width = rs;
region.height = bh;
+ if (do_clip) {
+ fb_clip_region((struct fb_region *) ®ion, &clip);
+ if (!region.width || !region.height)
+ return;
+ }
info->fbops->fb_fillrect(info, ®ion);
}
}
@@ -490,6 +591,28 @@
cursor.set |= FB_CUR_SETSIZE;
}
+ if (!(info->caps & FB_CAPS_CLIPPING) &&
+ (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+ vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+ struct fb_region clip, test;
+
+ clip.dx = clip.dy = 0;
+ clip.width = info->var.xres_virtual;
+ clip.height = info->var.yres_virtual;
+ test.dx = xx * width;
+ test.dy = yy * height;
+ test.width = width;
+ test.height = height;
+
+ /*
+ * we place cursor at screenpos(0,0) and hide it :-)
+ */
+ if (test_clip(&clip, &test)) {
+ xx = 0; yy = 0;
+ flags &= ~FB_CUR_SETCUR;
+ }
+ }
+
if ((vc->vc_cursor_type & 0x0f) != shape) {
shape = vc->vc_cursor_type & 0x0f;
cursor.set |= FB_CUR_SETSHAPE;
@@ -1173,6 +1296,18 @@
image.depth = 1;
image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
+ if (!(info->caps & FB_CAPS_CLIPPING) &&
+ (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+ vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+ struct fb_region clip;
+
+ clip.dx = clip.dy = 0;
+ clip.width = info->var.xres_virtual;
+ clip.height = info->var.yres_virtual;
+ if (test_clip(&clip, (struct fb_region *) &image))
+ return;
+ }
+
info->fbops->fb_imageblit(info, &image);
if (redraw_cursor)
@@ -1917,7 +2052,9 @@
conp2->vc_top = 0;
logo_shown = -1;
}
- if (info)
+ fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
+ p->vrows = info->var.yres_virtual/vc->vc_font.height;
+ if (info)
info->var.yoffset = p->yscroll = 0;
switch (p->scrollmode & __SCROLL_YMASK) {
case __SCROLL_YWRAP:
@@ -1937,7 +2074,6 @@
info->currcon = unit;
- fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
update_var(unit, info);
fbcon_set_palette(vc, color_table);
diff -Naur linux-2.5.54/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.5.54/drivers/video/fbmem.c 2003-01-09 13:52:13.000000000 +0000
+++ linux/drivers/video/fbmem.c 2003-01-10 03:40:17.000000000 +0000
@@ -368,6 +368,134 @@
#define LOGO_H 80
#define LOGO_W 80
+/**
+ * fb_clip_region: software clipping
+ * @region: area to clip
+ * @clip: clipping coordinates
+ */
+void fb_clip_region(struct fb_region *region,
+ const struct fb_region *clip)
+{
+ u32 clipx2 = clip->dx + clip->width;
+ u32 clipy2 = clip->dy + clip->height;
+
+ if (region->dx > clipx2) {
+ region->dx = clipx2;
+ region->width = 0;
+ }
+
+ if (region->dy > clipy2) {
+ region->dy = clipy2;
+ region->height = 0;
+ }
+
+ if (region->dx < clip->dx)
+ region->dx = clip->dx;
+
+ if (clipx2 < region->dx + region->width)
+ region->width = clipx2 - region->dx;
+
+ if (region->dy < clip->dy)
+ region->dy = clip->dy - region->dy;
+
+ if (clipy2 < region->dy + region->height)
+ region->height = clipy2 - clip->dy;
+}
+
+/**
+ * fb_clip_region2: software clipping
+ * @d_region: dst area to clip
+ * @s_region: src area to clip
+ * @clip: clipping coordinates
+ */
+void fb_clip_region2(struct fb_region *d_region,
+ struct fb_region *s_region,
+ const struct fb_region *clip)
+{
+ u32 clipx2 = clip->dx + clip->width;
+ u32 clipy2 = clip->dy + clip->height;
+ u32 dx2, dy2, sx2, sy2;
+
+ if (d_region->dx > clipx2) {
+ d_region->dx = clipx2;
+ d_region->width = 0;
+ }
+
+ if (d_region->dy > clipy2) {
+ d_region->dy = clipy2;
+ d_region->height = 0;
+ }
+
+ if (s_region->dx > clipx2) {
+ s_region->dx = clipx2;
+ s_region->width = 0;
+ }
+
+ if (s_region->dy > clipy2) {
+ s_region->dy = clipy2;
+ s_region->height = 0;
+ }
+
+ /* clip source, against destination */
+ if (d_region->dx < clip->dx) {
+ dx2 = d_region->dx + d_region->width;
+ s_region->width = (clip->width < dx2 - clip->dx) ?
+ clip->width : dx2 - clip->dx;
+ s_region->dx += clip->dx - d_region->dx;
+ d_region->dx = clip->dx;
+ }
+
+ dx2 = d_region->dx + s_region->width;
+ if (clipx2 < dx2)
+ s_region->width = clipx2 - d_region->dx;
+
+ d_region->width = s_region->width;
+
+ if (d_region->dy < clip->dy) {
+ dy2 = d_region->dy + d_region->height;
+ s_region->height = (clip->height < dy2 - clip->dy) ?
+ clip->height : dy2 - clip->dy;
+ s_region->dy += clip->dy - d_region->dy;
+ d_region->dy = clip->dy;
+ }
+
+ dy2 = d_region->dy + s_region->height;
+ if (clipy2 < dy2)
+ s_region->height = clipx2 - d_region->dy;
+
+ d_region->height = s_region->height;
+
+ /* not guaranteed that source is within bounds, so... */
+ /* clip destination, against source */
+ if (s_region->dx < clip->dx) {
+ sx2 = s_region->dx + s_region->width;
+ d_region->width = (clip->width < sx2 - clip->dx) ?
+ clip->width : sx2 - clip->dx;
+ d_region->dx += clip->dx - s_region->dx;
+ s_region->dx = clip->dx;
+ }
+
+ sx2 = s_region->dx + d_region->width;
+ if (clipx2 < sx2)
+ d_region->width = clipx2 - s_region->dx;
+
+ s_region->width = d_region->width;
+
+ if (s_region->dy < clip->dy) {
+ sy2 = s_region->dy + s_region->height;
+ d_region->height = (clip->height < sy2 - clip->dy) ?
+ clip->height : sy2 - clip->dy;
+ d_region->dy += clip->dy - s_region->dy;
+ s_region->dy = clip->dy;
+ }
+
+ sy2 = s_region->dy + d_region->height;
+ if (clipy2 < sy2)
+ d_region->height = clipx2 - s_region->dy;
+
+ s_region->height = d_region->height;
+}
+
static inline unsigned safe_shift(unsigned d, int n)
{
return n < 0 ? d >> -n : d << n;
@@ -1189,5 +1317,7 @@
EXPORT_SYMBOL(fb_set_var);
EXPORT_SYMBOL(fb_blank);
EXPORT_SYMBOL(fb_pan_display);
+EXPORT_SYMBOL(fb_clip_region);
+EXPORT_SYMBOL(fb_clip_region2);
MODULE_LICENSE("GPL");
diff -Naur linux-2.5.54/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.5.54/include/linux/fb.h 2003-01-09 13:52:49.000000000 +0000
+++ linux/include/linux/fb.h 2003-01-09 13:51:41.000000000 +0000
@@ -173,6 +173,9 @@
#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+/* Driver Capability */
+#define FB_CAPS_CLIPPING 1 /* hardware can do clipping */
+
#define PICOS2KHZ(a) (1000000000UL/(a))
#define KHZ2PICOS(a) (1000000000UL/(a))
@@ -394,6 +397,7 @@
void *pseudo_palette; /* Fake palette of 16 colors and
the cursor's color for non
palette mode */
+ int caps; /* Driver capability, see FB_CAPS_* */
/* From here on everything is device dependent */
void *par;
};
@@ -461,6 +465,11 @@
extern int register_framebuffer(struct fb_info *fb_info);
extern int unregister_framebuffer(struct fb_info *fb_info);
extern int fb_show_logo(struct fb_info *fb_info);
+extern void fb_clip_region(struct fb_region *region,
+ const struct fb_region *clip);
+extern void fb_clip_region2(struct fb_region *s_region,
+ struct fb_region *d_region,
+ const struct fb_region *clip);
extern struct fb_info *registered_fb[FB_MAX];
extern int num_registered_fb;
|
|
From: Geert U. <ge...@li...> - 2003-01-10 10:47:13
|
On 10 Jan 2003, Antonino Daplas wrote:
> On Fri, 2003-01-10 at 05:24, James Simmons wrote:
> > > So perhaps, a function something like this:
> > >
> > > void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);
> > >
> > > This should not be difficult to implement, and I'll code it if everyone
> > > agrees.
> >
> > I thought about this. Originally I did have this function but removed it.
> > WHat do you think Geert?
> >
> > > The other option (which I don't like) is just to check the passed
> > > fb_var_screeninfo in the put_var ioctl against the current console
> > > window size. But this is not foolproof as we will not be sure of the
> > > resulting window size _after_ the fb_set_var() call.
> >
> > Yuck!!! The other way is better.
> >
>
> Yes, I thought so too :-).
>
> I think one scenario why we need clipping is changing bits_per_pixel,
> ie, changing from 8->16 will drop your vyres by half and it's difficult
> to determine this unless you do another check before the set_par(), as
> Geert mentioned. Worse still, there is little if no valid memory past
> vyres but the console thinks there is. That's where you will get a
> segfault.
>
> Whereas explicitly doing fbset -vyres 768 will not cause a segfault,
> because you still have valid framebuffer memory past y=768.
That depends. On unified memory architectures or if the graphics memory is
shared by two heads, you may still corrupt someone's memory.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: Antonino D. <ad...@po...> - 2003-01-10 10:39:20
|
On Fri, 2003-01-10 at 02:16, James Simmons wrote: > > > BTW, is it possible that someone passes data that is larger (except for bugs)? > > We have control over what happens in the kernel. Data passed from userspace is > > a different issue, of course. > > Yes. Soon the standard ioctl for a cursor will be truly in place. This > means cfb_imageblit could be a issue from userland. > If you are going to export the cursor API to userland, then soft_cursor is useless, because it implies that we always have a copy of the screen under the cursor (so we can restore it when we move the cursor) and it also implies that fb_imageblit can support transparency (so the mask bits will work). For soft cursors, the userland has to take care of it. For those with hardware cursors, this is exportable to user space. The structure fbcursor has one field that is console specific fbcursor.dest which we basically use to invert the cursor image. So the structure that is passed via the cursor ioctl will be slightly different, it should not have the 'dest' field. So when it gets passed to fb_cursor(), dest == NULL. Then this is how drivers can respond: 1. soft_cursor - if cursor->dest == NULL, always exit with an error. 2. hardware cursors which cannot do invert - if cursor->dest == NULL and rop == ROP_XOR, exit with an error, otherwise (ROP_COPY), proceed. 3. hardware cursors with invert - cursor->dest will be ignored so it has full support. The rivafb_cursor() and i810fb_cursor() already behaves like #2 already. Anyway, inverting the cursor image is not commonly used in GUI apps. Typically, they just need an opaque cursor + a transparency mask to "shape" the cursor. Tony |