edward shu wrote: > > Jan Setje-Eilers: >> Garrett D'Amore wrote: >>> Edward Shu wrote: >>>> >>>> I think there are two concepts to be clarified, VGA text console >>>> and VESA text console. VGA text console is the legacy way. >>>> In this proposal, you may mean the VESA text console when >>>> text console is mentioned, that emulates the text output with >>>> the VESA graphics mode. As VESA is a generic graphics >>>> standard with few hardware specific acceleration, the text >>>> rendering speed will be much slower causing flicking screen. >>>> I recommend to reserve some open interfaces for third-party to >>>> fully accelerating the text rendering under VESA text mode. >>>> Other comments in lines below. >>> >>> I agree with this.. specifically I can see that *scrolling* can be >>> slow if not accelerated. > So my concern is, if we want to add the hardware accerlerated > "scrolling" in the future for a specific > chip, we can do it very straightly. So as the "text font > rendering", the "bitblt" and others. As I said in the previous reply, I've added a specific callback function that any driver can call to register bitblt, copy and alike operations. This is as simple as calling a function and the module provided routines will take precedence on standard, non-accelerated, VESA routines:
(from: http://push/builds/enrico/vesa-dev/vesa-gate/webrev/usr/src/uts/i86pc/io/gfx_private/gfxp_bitmap.c.html -- at http://push/builds/enrico/vesa-dev/vesa-gate/webrev/ there is a quite recent webrev which lacks the work I'm doing to collapse consoled and vbiosd into a single daemon) 97 static struct gfxp_ops fb_ops = { 98 gfxp_bm_kdsetmode, /* kdsetmode */ 99 gfxp_bm_devinit, /* devinit */ 100 gfxp_bm_cons_copy, /* conscopy */ 101 gfxp_bm_cons_display, /* consdisplay */ 102 gfxp_bm_cons_cursor, /* conscursor */ 103 gfxp_bm_cons_clear, /* consclear */ 104 gfxp_bm_suspend, /* suspend */ 105 gfxp_bm_resume, /* resume */ 106 gfxp_bm_devmap /* devmap */ 107 }; 108 109 /* 110 * Generic drawing functions. 111 * These functions emulate in software the blit/copy of a square/rectangle on 112 * the screen. They are used by default and, right now, in the vast majority (if 113 * not the totality) of cases. If a graphic driver supports hardware blitting 114 * it can register a function callbacks via gfxp_bm_register_fbops(). 115 * NOTE that these functions are also used in polled I/O mode, and are so 116 * subject to its limitations. 117 */ 118 static void gfxp_bm_generic_blt(struct gfxp_softc *softc, 119 struct vis_consdisplay *); 120 static void gfxp_bm_generic_copy(struct gfxp_softc *softc, 121 struct vis_conscopy *); 122 (NOTE: the gfxp_bm_suspend/resume might go away. It depends if ever a driver may need to get control back - after - calling into gfx_private routines but before they return. Debatable. No driver currently consumes these). Then the registering function looks like: 236 /* 237 * Public functions to register and unregister driver routines with the 238 * generic gfx driver. NOTE: FBCONS macro expects the vgatext_softc structure 239 * pointer to be called 'softc'. 240 */ 241 void 242 gfxp_bm_register_fbops(gfxp_vgatext_softc_ptr_t ptr, struct gfxp_blt_ops *fbops) 243 { 244 struct gfxp_softc *softc = (struct gfxp_softc *)ptr; 245 FBCONS.fbops = fbops; 246 } 247 248 void 249 gfxp_bm_unregister_fbops(gfxp_vgatext_softc_ptr_t ptr) 250 { 251 struct gfxp_softc *softc = (struct gfxp_softc *)ptr; 252 FBCONS.fbops = NULL; 253 } And taking as an example the blit function: 438 static void 439 gfxp_bm_cons_display(struct gfxp_softc *softc, struct vis_consdisplay *da) 440 { 441 /* Sanitize input. */ 442 if (da->col < 0 || da->col >= FBCONS.xres || 443 da->row < 0 || da->row >= FBCONS.yres || 444 da->col + da->width > FBCONS.xres || 445 da->row + da->height > FBCONS.yres) { 446 return; 447 } 448 449 /* 450 * If we are in "console mode", update the screen. 451 * Use an hardware provided blt function, if possible, otherwise 452 * fallback to gfxp_bm_generic_blt(). 453 */ 454 if (FBCONS.active == 1) { 455 if (FBCONS.fbops == NULL || FBCONS.fbops->blt == NULL || 456 FBCONS.fbops->blt(da) != GFXP_SUCCESS) 457 gfxp_bm_generic_blt(softc, da); 458 459 /* Flush to memory. */ 460 membar_producer(); 461 } 462 /* Update the shadow buffer. */ 463 gfxp_bm_blt_updtshadow(softc, da); 464 } Where at 454 - 456 we call the driver function if present and fallback to the standard method if -for any reason- it fails. We -always- need to update the shadow buffer and that's done transparently to the driver. Why it is not more stabilized? First and foremost: nowadays graphics card memory and modern CPUs are fast. By touching the framebuffer memory only on writing (keeping a shadow frame buffer) and by setting the memory as write-combining, performances have been satisfactory so far. We had a test with the Look'n'Feel guys where they felt okay about the scrolling result (the rule of thumb they suggested was: "If the user cannot read what's written on the screen during a scrolling, then it's okay") and I'm more than happy to have more. I'm also happy to prepare some archives so that you can try it yourself and very happy to code any potential improvement. Second of all we have 2-3 ways of doing the same thing inside the Solaris kernel. Intel uses the DRM interface, while NVIDIA needs to call a set of 'dedicated' interfaces (provided by gfx_private). This is, besides the old atiatom.c code, as much of video graphic support as we currently have on x86/x86_64. We don't have a well established DDI interface for graphics, which would probably be the best direction to head towards. But that is, in my opinion, out of the scope of this project. Third, we still only have two drivers, one of which is closed source (so we don't have direct access to it and, as per off-line discussion, is not headed towards supporting console framebuffer accelerated routines). We can see how the aforementioned interface plays out and, at the same time, see in what direction we go (are we planning to have more in-kernel graphic drivers? are we targeting laptops or not?) and plan accordingly. All the framebuffer painting routines are reasonably generic and used both in the early stages (e.g. KMDB) and after the coherent console kicks in. Note also that this project actually solves a bit of duplication (probably a low hanging fruit, but still a couple hundreds of lines cut off): the vgatext module (which was loaded independently of gfx_private) is now a gfx_private consumer. While gfx_private does (always in my opinion) a little more than what it might be supposed to (it both acts as a pseudo-driver and actively draws on the screen), with the current architecture it is not a bad compromise. Also, depending on how fast EFI systems catch on we need the ability of generically draw on a bit mapped space, because it might be the only option we are left with. - Enrico > > >
