vbox5: react on host size changes immediately

The guest may take some time to adjust nevertheless.

Fixes #3498
This commit is contained in:
Alexander Boettcher 2019-09-15 16:56:27 +02:00 committed by Christian Helmuth
parent c5706e8f4a
commit ed73feddc5
2 changed files with 36 additions and 39 deletions

View File

@ -278,7 +278,7 @@ lappend_if [expr $use_top] boot_modules top
lappend_if [expr $use_gui] boot_modules report_rom
append boot_modules {
ld.lib.so libc.lib.so vfs.lib.so libm.lib.so libc_pipe.lib.so
libc.lib.so vfs.lib.so libm.lib.so libc_pipe.lib.so
libiconv.lib.so stdcxx.lib.so
qemu-usb.lib.so
}

View File

@ -37,12 +37,7 @@ class Genodefb :
Nitpicker::Connection &_nitpicker;
Fb_Genode::Session &_fb;
View_handle _view;
/* The mode at the time when the mode change signal was received */
Fb_Genode::Mode _next_fb_mode { 1024, 768, Fb_Genode::Mode::RGB565 };
/* The mode matching the currently attached dataspace */
Fb_Genode::Mode _fb_mode;
Fb_Genode::Mode _fb_mode { 1024, 768, Fb_Genode::Mode::RGB565 };
/*
* The mode currently used by the VM. Can be smaller than the
@ -55,20 +50,21 @@ class Genodefb :
void _clear_screen()
{
size_t const num_pixels = _fb_mode.width() * _virtual_fb_mode.height();
size_t const max_h = Genode::min(_fb_mode.height(), _virtual_fb_mode.height());
size_t const num_pixels = _fb_mode.width() * max_h;
memset(_fb_base, 0, num_pixels * _fb_mode.bytes_per_pixel());
_fb.refresh(0, 0, _virtual_fb_mode.width(), _virtual_fb_mode.height());
}
void _adjust_buffer()
{
_nitpicker.buffer(Fb_Genode::Mode(_next_fb_mode.width(), _next_fb_mode.height(),
_nitpicker.buffer(Fb_Genode::Mode(_fb_mode.width(), _fb_mode.height(),
Fb_Genode::Mode::RGB565), false);
typedef Nitpicker::Session::Command Command;
Nitpicker::Rect rect(Nitpicker::Point(0, 0),
Nitpicker::Area(_next_fb_mode.width(), _next_fb_mode.height()));
Nitpicker::Area(_fb_mode.width(), _fb_mode.height()));
_nitpicker.enqueue<Command::Geometry>(_view, rect);
_nitpicker.execute();
@ -85,7 +81,7 @@ class Genodefb :
_nitpicker.enqueue<Command::To_front>(_view, View_handle());
_nitpicker.execute();
return _next_fb_mode;
return _fb_mode;
}
public:
@ -95,22 +91,28 @@ class Genodefb :
_env(env),
_nitpicker(nitpicker),
_fb(*nitpicker.framebuffer()),
_fb_mode(_initial_setup()),
_virtual_fb_mode(_fb_mode),
_virtual_fb_mode(_initial_setup()),
_fb_base(env.rm().attach(_fb.dataspace()))
{
int rc = RTCritSectInit(&_fb_lock);
Assert(rc == VINF_SUCCESS);
}
/* Return the next mode of the framebuffer */
int w() const { return _next_fb_mode.width(); }
int h() const { return _next_fb_mode.height(); }
int w() const { return _fb_mode.width(); }
int h() const { return _fb_mode.height(); }
void update_mode(Fb_Genode::Mode mode)
{
Lock();
_next_fb_mode = mode;
_fb_mode = mode;
_env.rm().detach(_fb_base);
_adjust_buffer();
_fb_base = _env.rm().attach(_fb.dataspace());
Unlock();
}
@ -131,42 +133,33 @@ class Genodefb :
Lock();
bool ok = (w <= (ULONG)_next_fb_mode.width()) &&
(h <= (ULONG)_next_fb_mode.height());
bool ok = (w <= (ULONG)_fb_mode.width()) &&
(h <= (ULONG)_fb_mode.height());
if (ok) {
Genode::log("fb resize : [", screen, "] ",
_virtual_fb_mode.width(), "x",
_virtual_fb_mode.height(), " -> ",
w, "x", h,
" (host: ", _next_fb_mode.width(), "x",
_next_fb_mode.height(), ")");
" (host: ", _fb_mode.width(), "x",
_fb_mode.height(), ")");
if ((w < (ULONG)_next_fb_mode.width()) ||
(h < (ULONG)_next_fb_mode.height())) {
if ((w < (ULONG)_fb_mode.width()) ||
(h < (ULONG)_fb_mode.height())) {
/* clear the old content around the new, smaller area. */
_clear_screen();
}
_fb_mode = _next_fb_mode;
_virtual_fb_mode = Fb_Genode::Mode(w, h, Fb_Genode::Mode::RGB565);
_env.rm().detach(_fb_base);
_adjust_buffer();
_fb_base = _env.rm().attach(_fb.dataspace());
result = S_OK;
} else
Genode::log("fb resize : [", screen, "] ",
_virtual_fb_mode.width(), "x",
_virtual_fb_mode.height(), " -> ",
w, "x", h, " ignored"
" (host: ", _next_fb_mode.width(), "x",
_next_fb_mode.height(), ")");
" (host: ", _fb_mode.width(), "x",
_fb_mode.height(), ")");
Unlock();
@ -201,9 +194,11 @@ class Genodefb :
PRUint32 imageSize,
PRUint8 *image) override
{
Nitpicker::Area area_fb = Nitpicker::Area(_fb_mode.width(),
_fb_mode.height());
Nitpicker::Area area_vm = Nitpicker::Area(width, height);
Lock();
Nitpicker::Area const area_fb = Nitpicker::Area(_fb_mode.width(),
_fb_mode.height());
Nitpicker::Area const area_vm = Nitpicker::Area(width, height);
using namespace Genode;
@ -217,6 +212,8 @@ class Genodefb :
_fb.refresh(o_x, o_y, area_vm.w(), area_vm.h());
Unlock();
return S_OK;
}
@ -234,8 +231,8 @@ class Genodefb :
if (!supported)
return E_POINTER;
*supported = ((width <= (ULONG)_next_fb_mode.width()) &&
(height <= (ULONG)_next_fb_mode.height()));
*supported = ((width <= (ULONG)_fb_mode.width()) &&
(height <= (ULONG)_fb_mode.height()));
return S_OK;
}