vbox5: react on host size changes immediately
The guest may take some time to adjust nevertheless. Fixes #3498
This commit is contained in:
parent
c5706e8f4a
commit
ed73feddc5
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue