Skip to contentSkip to conversation

Restoring Screen when coming back from KD_GRAPHICS

PATCH John Zielinski 2 participants 7 messages Nov 26, 2003 – Dec 25, 2003

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

I was playing with the fbtest program and noticed some minor glitches. You could see corruption in the graphics where the console was still trying to output text from the program. After exiting the program's output would mix in with the saved screen.

So I modified the fbtest program to do ioctl to KD_GRAPHICS at startup and KD_TEXT on exit and the graphics corruption went away. I also didn't save/restore the framebuffer if we started in KD_TEXT on entry. This made things worse as now the graphics output was still plus the old text and the programs output would now appear after scrolling one line.

I checked the kernel to see why the screen wasn't being refreshed when switching back to KD_TEXT. I found that if the fbdev driver has a blanking routine the fbcon driver doesn't do a update_screen call. And the fbdev if it's using vesa blanking doesn't restore the screen nor does it return 1 to tell the vt driver to redraw the screen.

So here's a small patch that makes fbcon always restore the screen after the screen is unblanked:

drivers/video/console/fbcon.c +0 -0
diff -urNX dontdiff fbdev/drivers/video/console/fbcon.c linux/drivers/video/console/fbcon.c
@@ -1688,11 +1688,13 @@
				accel_clear(vc, info, real_y(p, 0),
					    0, height, vc->vc_cols);
			vc->vc_video_erase_char = oldc;

- } else
- update_screen(vc->vc_num);
- return 0;
+ }

	} else

- return fb_blank(info, blank);
+ fb_blank(info, blank);
+
+ if (!blank)
+ update_screen(vc->vc_num);
+ return 0;
}

static void fbcon_free_font(struct display *p)

I think that this is the simplest way of doing it as the other two options would require to either change the vt driver to send a leaving KD_TEXT call or to change the fbcon driver to remember if each console was in graphics mode or not.

John

-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program. Does SourceForge.net help you be more productive? Does it help you create better code? SHARE THE LOVE, and help us help YOU! Click Here: http://sourceforge.net/donate/

#1 lore raw
Quoted 11 lines · John Zielinski

I was playing with the fbtest program and noticed some minor glitches. You could see corruption in the graphics where the console was still trying to output text from the program. After exiting the program's output would mix in with the saved screen.

So I modified the fbtest program to do ioctl to KD_GRAPHICS at startup and KD_TEXT on exit and the graphics corruption went away. I also didn't save/restore the framebuffer if we started in KD_TEXT on entry. This made things worse as now the graphics output was still plus the old text and the programs output would now appear after scrolling one line.

Quoted 7 lines

I checked the kernel to see why the screen wasn't being refreshed when
switching back to KD_TEXT. I found that if the fbdev driver has a
blanking routine the fbcon driver doesn't do a update_screen call. And the fbdev if it's using vesa blanking doesn't restore the screen nor does it return 1 to tell the vt driver to redraw the screen.

.../...

That's an old problem, I think your patch isn't enough though, we really need to first callback into the fbdev layer with some sort of "restore state" call so we have a chance to restore the palette and accel engine status properly (and maybe even the mode).

Basically, when switching to KD_TEXT, we switch from userland having taken control of the HW (either partially, that is only the accel engine, or completely including mode setting) back to kernel control. At this point, we need to restore the HW in a known state, we can't rely on userland to do it properly (and that's not always possible) while it's very simple for us to do it from the fbdev.

It's on my todolist of things to fix, but still I lack time, if you feel like implementing the background (we can fix individual drivers later on) support for that, go on :)

Regards,
Ben.

-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click

#2 lore raw
Quoted 12 lines · Benjamin Herrenschmidt

That's an old problem, I think your patch isn't enough though, we really need to first callback into the fbdev layer with some sort of "restore state" call so we have a chance to restore the palette and accel engine status properly (and maybe even the mode).

Basically, when switching to KD_TEXT, we switch from userland having taken control of the HW (either partially, that is only the accel engine, or completely including mode setting) back to kernel control. At this point, we need to restore the HW in a known state, we can't rely on userland to do it properly (and that's not always possible) while it's very simple for us to do it from the fbdev.

Quoted 5 lines

It's on my todolist of things to fix, but still I lack time, if you feel like implementing the background (we can fix individual drivers later on) support for that, go on :)

I'll take a look. This fits well with what I'm trying to do with the mode switching between virtual terminals. The callback will definately be neccessarry to tell the driver to save any driver specific data that I'm not already saving (ie anything that's not defined in fb.h).

John

-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click

#3 lore raw
Quoted 5 lines

I'll take a look. This fits well with what I'm trying to do with the mode switching between virtual terminals. The callback will definately be neccessarry to tell the driver to save any driver specific data that I'm not already saving (ie anything that's not defined in fb.h).

I don't think we need to "save" anything, there is no way I want any knowledge of fbcon-specific stuff to go back into fbdev's, it was hard enough to split these properly (that's a good thing James did).

I think we just need to instruct the fbdev to restore it's mode via a set_var with an activate flag FB_ACTIVATE_FORCE, that bypass any test inside the driver about the mode changing from the current info-var, that is basically forcing it to re-apply it's current var. Most drivers will also reset the accel engine properly if any when doing so.

Ben.

-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click

#4 lore raw
Quoted 5 lines · Benjamin Herrenschmidt

I don't think we need to "save" anything, there is no way I want any knowledge of fbcon-specific stuff to go back into fbdev's, it was hard enough to split these properly (that's a good thing James did).

I was using "save" as in "don't overwrite". The fb_var_screeninfo and fb_cmap structures are the two main ones. If we have seperate ones for each vt and one for when a graphics app then the contents of each is "saved" and can be restored by fbcon very easily.

But if a fbdev can't recreate it's state from the information that fbcon provides (var, cmap, etc) because it has some internal driver or hw state info then there needs to be a way for fbcon to tell the fbdev "put your internal state in this buffer" so it can be remembered when things get restored later. That way the fbdev doesn't have to worry about any of the high level stuff. It just gets the contents of that buffer back when things get restored. Fbcon can ask the driver on startup as to how many bytes of buffer space does it need for it's save area and if the fbdev doesn't need any (it can totally restore it's state using the normal set_var mechanism) it can just say zero.

Quoted 7 lines

I think we just need to instruct the fbdev to restore it's mode via a set_var with an activate flag FB_ACTIVATE_FORCE, that bypass any test inside the driver about the mode changing from the current info-var, that is basically forcing it to re-apply it's current var. Most drivers will also reset the accel engine properly if any when doing so.

Can all the fbdevs restore everything with just that information? If so then we don't have to worry about the internal state save buffer stuff above.

John

-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click

#5 lore raw
Quoted 5 lines

I was using "save" as in "don't overwrite". The fb_var_screeninfo and
fb_cmap structures are the two main ones. If we have seperate ones for each vt and one for when a graphics app then the contents of each is "saved" and can be restored by fbcon very easily.

Ok.

Quoted 10 lines

But if a fbdev can't recreate it's state from the information that fbcon provides (var, cmap, etc) because it has some internal driver or hw state info then there needs to be a way for fbcon to tell the fbdev "put your internal state in this buffer" so it can be remembered when things get restored later. That way the fbdev doesn't have to worry about any of the high level stuff. It just gets the contents of that buffer back
when things get restored. Fbcon can ask the driver on startup as to
how many bytes of buffer space does it need for it's save area and if the fbdev doesn't need any (it can totally restore it's state using the normal set_var mechanism) it can just say zero.

I think we don't need (nor want) to go down that path. And I fail to see what state info would matter anyway.

Quoted 11 lines
Quoted 7 lines

I think we just need to instruct the fbdev to restore it's mode via a set_var with an activate flag FB_ACTIVATE_FORCE, that bypass any test inside the driver about the mode changing from the current info-var, that is basically forcing it to re-apply it's current var. Most drivers will also reset the accel engine properly if any when doing so.

Can all the fbdevs restore everything with just that information? If
so then we don't have to worry about the internal state save buffer stuff above.

The fbdev's can restore what they need. What I mean is they can restore the whole state needed for the mode, the palette and their own accel ops to behave properly. That's all they have to care about. If a gfx app need more engine state, it's up to this app to save/restore it.

ben.

-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click

#6 lore raw
Quoted 10 lines · Benjamin Herrenschmidt

I think we don't need (nor want) to go down that path. And I fail to see what state info would matter anyway.

The fbdev's can restore what they need. What I mean is they can restore the whole state needed for the mode, the palette and their own accel ops to behave properly. That's all they have to care about. If a gfx app need more engine state, it's up to this app to save/restore it.

Good. Then I don't have to worry about that then.

John

-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click