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 lappend_if [expr $use_gui] boot_modules report_rom
append boot_modules { 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 libiconv.lib.so stdcxx.lib.so
qemu-usb.lib.so qemu-usb.lib.so
} }

View File

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