Re: [Qemu-devel] Question about hardware cursor in VGA
On Thu, 7 Mar 2019, BALATON Zoltan wrote: I still have the unfinished version using the callbacks which might work with force_shadow like for cirrus but I'd need to finish and clean that up. Now that we have both implemented probably will allow switching between them but may not be able to do it before the freeze so don't wait for that. (The define_cursor way is enough for testing at the moment and rewriting it to use different callback could be considered bugfix or added in next devel cycle as well.) I've sent a v6 now (of just the ati-vga patch, the other patch in the series is unchanged) with this. Defaults to define_cursor but cursor rendering via callbacks can be enabled with guest_hwcursor=true property. The cursor seems to be less jumpy with it but probably slower. I'm still not sure why it jumps with define_cursor but I think that may be a problem outside of this device. I've also attempted to implement DDC for EDID but that's not ready yet and it will be a separate series because I'll likely need some changes to i2c as well to be able to use bitbang_i2c in this device model. (Probably we should merge contents of hw/bitbang_i2c.h in include/hw/i2c.h where the structure definition had to be moved already or move this header to include to be able to use it outside of hw/i2c. Currently I just #include "../i2c/bitbang_i2c.h" from hw/display/ati.c but I think that's not acceptable.) Regards, BALATON Zoltan
Re: [Qemu-devel] Question about hardware cursor in VGA
On Thu, 7 Mar 2019, Gerd Hoffmann wrote: On Wed, Mar 06, 2019 at 02:50:36PM +0100, BALATON Zoltan wrote: On Wed, 6 Mar 2019, Gerd Hoffmann wrote: On Wed, Mar 06, 2019 at 12:48:59AM +0100, BALATON Zoltan wrote: On Tue, 5 Mar 2019, Gerd Hoffmann wrote: Use dpy_cursor_define(). I've done that but it's not working very well. The mouse pointer is quite jumpy with this and there are some problems updating the pointer image when the guest changes image data in video ram without changing registers. (Like When using a relative pointing device (i.e. mouse instead of tablet) you also need dpy_mouse_set(), to update the host mouse position when the guest moves the cursor sprite around. Sure, I figured that out otherwise the mouse pointer would not move. Is it possible to figure where the cursor hotspot is? Not sure what you mean. I call dpy_mouse_set() on writing the reg that contains mouse position. Hot spot is always top left of sprite (or I don't know where it's set). I'll submit a v5 after adding some more checks to make it a bit safer then you can have a look. Well, paravirtual graphics devices propagate the hot-spot information from the guest to the host. But on real hardware you typically don't have registers for that information as the GPU doesn't need to know the hotspot for cursor display. The guest driver can simply take the hotspot location into account when programming the cursor position into the hardware registers. So, the suggestion to use dpy_cursor_define() wasn't a good one after all. I totally forgot about the hotspot issue as I work with paravirtual graphics devices most of the time. Sorry for that. Hmm, OK but this still does not explain why mouse is jumping when it's just moved around without changing the image. least doing hw cursor like this works somewhat but I note that the other version with cursor_invalidate and cursor_draw_line callbacks worked much smoother, alas I've found that cannot work with shared_surface. There is a VGAComminState->force_shadow ... Yes, but that would also make things slower so I like to keep advantage of shared_surface and try to fix the jumpy mouse we get with define_cursor instead if possible. Its not so much a performance issue. But you need a round-trip to the guest to update the cursor position, which adds noticeable latency to mouse moves ... It's not a big performance issue when rendering the mouse but may be when rendering the screen having to copy contents to the display surface at each refresh (at least the part that changed) instead of using it directly from guest VRAM with shared_surface where this copy is avoided if I got that right. I still have the unfinished version using the callbacks which might work with force_shadow like for cirrus but I'd need to finish and clean that up. Now that we have both implemented probably will allow switching between them but may not be able to do it before the freeze so don't wait for that. (The define_cursor way is enough for testing at the moment and rewriting it to use different callback could be considered bugfix or added in next devel cycle as well.) Regards, BALATON Zoltan
Re: [Qemu-devel] Question about hardware cursor in VGA
On Wed, Mar 06, 2019 at 02:50:36PM +0100, BALATON Zoltan wrote: > On Wed, 6 Mar 2019, Gerd Hoffmann wrote: > > On Wed, Mar 06, 2019 at 12:48:59AM +0100, BALATON Zoltan wrote: > > > On Tue, 5 Mar 2019, Gerd Hoffmann wrote: > > > > Use dpy_cursor_define(). > > > > > > I've done that but it's not working very well. The mouse pointer is quite > > > jumpy with this and there are some problems updating the pointer image > > > when > > > the guest changes image data in video ram without changing registers. > > > (Like > > > > When using a relative pointing device (i.e. mouse instead of tablet) you > > also need dpy_mouse_set(), to update the host mouse position when the > > guest moves the cursor sprite around. > > Sure, I figured that out otherwise the mouse pointer would not move. > > > Is it possible to figure where the cursor hotspot is? > > Not sure what you mean. I call dpy_mouse_set() on writing the reg that > contains mouse position. Hot spot is always top left of sprite (or I don't > know where it's set). I'll submit a v5 after adding some more checks to make > it a bit safer then you can have a look. Well, paravirtual graphics devices propagate the hot-spot information from the guest to the host. But on real hardware you typically don't have registers for that information as the GPU doesn't need to know the hotspot for cursor display. The guest driver can simply take the hotspot location into account when programming the cursor position into the hardware registers. So, the suggestion to use dpy_cursor_define() wasn't a good one after all. I totally forgot about the hotspot issue as I work with paravirtual graphics devices most of the time. Sorry for that. > > > least doing hw cursor like this works somewhat but I note that the other > > > version with cursor_invalidate and cursor_draw_line callbacks worked much > > > smoother, alas I've found that cannot work with shared_surface. > > > > There is a VGAComminState->force_shadow ... > > Yes, but that would also make things slower so I like to keep advantage of > shared_surface and try to fix the jumpy mouse we get with define_cursor > instead if possible. Its not so much a performance issue. But you need a round-trip to the guest to update the cursor position, which adds noticeable latency to mouse moves ... Either that, or live with the offset due to the missing hotspot location. Which typically isn't that much of a problem with the left pointer where the hotspot is close to the upper left corner. With the caret (typically used in text fields) the offset is very noticable though. cheers, Gerd
Re: [Qemu-devel] Question about hardware cursor in VGA
On Wed, 6 Mar 2019, Gerd Hoffmann wrote: On Wed, Mar 06, 2019 at 12:48:59AM +0100, BALATON Zoltan wrote: On Tue, 5 Mar 2019, Gerd Hoffmann wrote: Use dpy_cursor_define(). I've done that but it's not working very well. The mouse pointer is quite jumpy with this and there are some problems updating the pointer image when the guest changes image data in video ram without changing registers. (Like When using a relative pointing device (i.e. mouse instead of tablet) you also need dpy_mouse_set(), to update the host mouse position when the guest moves the cursor sprite around. Sure, I figured that out otherwise the mouse pointer would not move. Is it possible to figure where the cursor hotspot is? Not sure what you mean. I call dpy_mouse_set() on writing the reg that contains mouse position. Hot spot is always top left of sprite (or I don't know where it's set). I'll submit a v5 after adding some more checks to make it a bit safer then you can have a look. least doing hw cursor like this works somewhat but I note that the other version with cursor_invalidate and cursor_draw_line callbacks worked much smoother, alas I've found that cannot work with shared_surface. There is a VGAComminState->force_shadow ... Yes, but that would also make things slower so I like to keep advantage of shared_surface and try to fix the jumpy mouse we get with define_cursor instead if possible. should be? (Also note that draw_line callback could do complement pixels but that's not possible with dpy_cursor_define.) Yep, dpy_cursor_define is designed for the way modern hardware handles hardware cursors, to allow it being used as hardware cursor on the host. cirrus has a few modes which modern hardware can't do, thats why it doesn't use dpy_cursor_define. Has ati cursor a complement pixel mode too? Yes, this part dates back to first ATI VGA chips is seem and has the 2 bit Windows mouse encoding (fg, bg, transparent, complement) but we can probably live without that if it gives us faster display for a few bad pixels in mouse pointer. Regards, BALATON Zoltan
Re: [Qemu-devel] Question about hardware cursor in VGA
On Wed, Mar 06, 2019 at 12:48:59AM +0100, BALATON Zoltan wrote: > On Tue, 5 Mar 2019, Gerd Hoffmann wrote: > > On Mon, Mar 04, 2019 at 03:58:00PM +0100, BALATON Zoltan wrote: > > > Hello, > > > > > > I'm trying to implement hardware cursor for ati-vga before submitting the > > > last version of it before the freeze. > > > > Use dpy_cursor_define(). > > I've done that but it's not working very well. The mouse pointer is quite > jumpy with this and there are some problems updating the pointer image when > the guest changes image data in video ram without changing registers. (Like When using a relative pointing device (i.e. mouse instead of tablet) you also need dpy_mouse_set(), to update the host mouse position when the guest moves the cursor sprite around. Is it possible to figure where the cursor hotspot is? > least doing hw cursor like this works somewhat but I note that the other > version with cursor_invalidate and cursor_draw_line callbacks worked much > smoother, alas I've found that cannot work with shared_surface. There is a VGAComminState->force_shadow ... > should be? (Also note that draw_line callback could do complement pixels but > that's not possible with dpy_cursor_define.) Yep, dpy_cursor_define is designed for the way modern hardware handles hardware cursors, to allow it being used as hardware cursor on the host. cirrus has a few modes which modern hardware can't do, thats why it doesn't use dpy_cursor_define. Has ati cursor a complement pixel mode too? cheers, Gerd
Re: [Qemu-devel] Question about hardware cursor in VGA
On Tue, 5 Mar 2019, Gerd Hoffmann wrote: On Mon, Mar 04, 2019 at 03:58:00PM +0100, BALATON Zoltan wrote: Hello, I'm trying to implement hardware cursor for ati-vga before submitting the last version of it before the freeze. Use dpy_cursor_define(). I've done that but it's not working very well. The mouse pointer is quite jumpy with this and there are some problems updating the pointer image when the guest changes image data in video ram without changing registers. (Like when it sets cursor data offset first, then writes image data in memory after that but QEMUCursor is created from the still empty data on setting the register.) I've managed to solve this latter problem (at least for the guest I care about) by allowing some unnecessary cursor updates but position changes remain erratic. I'll submit this version (after some more checking of 2d functions which still don't work well beyond simple cases) because at least doing hw cursor like this works somewhat but I note that the other version with cursor_invalidate and cursor_draw_line callbacks worked much smoother, alas I've found that cannot work with shared_surface. I'm not sure what causes this pointer position update problem. Could it be that pointer position updates are now independent of screen refresh with dpy_mouse_move so there's a higher chance of doing big jumps where the invalidate/draw_line callbacks were called from display update so they've sampled mouse position in smaller steps somehow? Or is it because mouse pointer is now a real hardware cursor which can be moved independent of the guest but any guest update will warp it back to where the guest thinks it should be? (Also note that draw_line callback could do complement pixels but that's not possible with dpy_cursor_define.) This also reminds me that jumpy mouse problem was also reported with MacOS guests before with the gtk UI I think (https://www.emaculation.com/forum/viewtopic.php?f=34=9750) but not sure if that's related to this or not. Also not sure what would be the best way to improve this: reviving at least the mouse invalidate callback and do dpy_mouse_move from there instead of calling it on register change? Or also fixing the draw_cursor_line callback with shared surface maybe by providing a separate surface for the mouse in that case for the device model to render the mouse into which then can be composited on the display surface somehow by the frontend? This may be problematic for remote displays and may also loose the advantage of the shared surface unless there's some hardware support for this so I'm not sure about that. But at least the jumpy cursor should be fixed somehow because that makes user experience with hardware cursor quite bad. Regards, BALATON Zoltan
Re: [Qemu-devel] Question about hardware cursor in VGA
On Mon, Mar 04, 2019 at 03:58:00PM +0100, BALATON Zoltan wrote: > Hello, > > I'm trying to implement hardware cursor for ati-vga before submitting the > last version of it before the freeze. Use dpy_cursor_define(). cheers, Gerd
[Qemu-devel] Question about hardware cursor in VGA
Hello, I'm trying to implement hardware cursor for ati-vga before submitting the last version of it before the freeze. (This was found to be used at least by MorphOS and Mac OS X.) I've found that vga has facilities for this already (used by cirrus) with the cursor_invalidate() and cursor_draw_line() functions that I can reuse for this but these are only called if !(is_buffer_shared(surface)) at least since 7d957bd8cbc. How is this supposed to work? What does draw hardware cursor in cirrus when surface is shared? Or is it broken now for cirrus as well? I could remove this check from vga.c and add it to the functions in cirrus-vga.c to preserve current behaviour but I'm not sure that's correct. Looks more like this check is not needed at all for cirrus either. Is there a guest to test this with? (This reminds me I've seen mouse pointer disappearing in text input fields and notepad or wordpad on WindowsXP guest before probably with vmware_vga but likely that's not related to the above, just remembered it now.) Regards, BALATON Zoltan