mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 08:25:38 +00:00
parent
cb3b6c4b88
commit
61454178c0
@ -43,14 +43,15 @@ void Vmm::Virtio_gpu_queue::notify(Virtio_gpu_device & dev)
|
|||||||
|
|
||||||
void Vmm::Virtio_gpu_control_request::_get_display_info()
|
void Vmm::Virtio_gpu_control_request::_get_display_info()
|
||||||
{
|
{
|
||||||
|
Framebuffer::Mode mode = _device.resize();
|
||||||
Display_info_response dir { _desc_addr(1) };
|
Display_info_response dir { _desc_addr(1) };
|
||||||
memset((void*)dir.base(), 0, Display_info_response::SIZE);
|
memset((void*)dir.base(), 0, Display_info_response::SIZE);
|
||||||
dir.write<Control_header::Type>(Control_header::Type::OK_DISPLAY_INFO);
|
dir.write<Control_header::Type>(Control_header::Type::OK_DISPLAY_INFO);
|
||||||
|
|
||||||
dir.write<Display_info_response::X>(0);
|
dir.write<Display_info_response::X>(0);
|
||||||
dir.write<Display_info_response::Y>(0);
|
dir.write<Display_info_response::Y>(0);
|
||||||
dir.write<Display_info_response::Width>(_device._fb_mode.area.w());
|
dir.write<Display_info_response::Width>(mode.area.w());
|
||||||
dir.write<Display_info_response::Height>(_device._fb_mode.area.h());
|
dir.write<Display_info_response::Height>(mode.area.h());
|
||||||
dir.write<Display_info_response::Enabled>(1);
|
dir.write<Display_info_response::Enabled>(1);
|
||||||
dir.write<Display_info_response::Flags>(0);
|
dir.write<Display_info_response::Flags>(0);
|
||||||
}
|
}
|
||||||
@ -182,6 +183,9 @@ void Vmm::Virtio_gpu_control_request::_resource_flush()
|
|||||||
uint32_t id = rf.read<Resource_flush::Resource_id>();
|
uint32_t id = rf.read<Resource_flush::Resource_id>();
|
||||||
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID);
|
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID);
|
||||||
|
|
||||||
|
if (!_device._fb_ds.constructed())
|
||||||
|
return;
|
||||||
|
|
||||||
using Resource = Virtio_gpu_device::Resource;
|
using Resource = Virtio_gpu_device::Resource;
|
||||||
_device._resources.for_each([&] (Resource & res) {
|
_device._resources.for_each([&] (Resource & res) {
|
||||||
if (res.id != id)
|
if (res.id != id)
|
||||||
@ -189,20 +193,23 @@ void Vmm::Virtio_gpu_control_request::_resource_flush()
|
|||||||
|
|
||||||
uint32_t x = rf.read<Resource_flush::X>();
|
uint32_t x = rf.read<Resource_flush::X>();
|
||||||
uint32_t y = rf.read<Resource_flush::Y>();
|
uint32_t y = rf.read<Resource_flush::Y>();
|
||||||
uint32_t w = rf.read<Resource_flush::Width>();
|
uint32_t w = min(rf.read<Resource_flush::Width>(),
|
||||||
uint32_t h = rf.read<Resource_flush::Height>();
|
_device._fb_mode.area.w() - x);
|
||||||
|
uint32_t h = min(rf.read<Resource_flush::Height>(),
|
||||||
|
_device._fb_mode.area.h() - y);
|
||||||
|
|
||||||
if (x > res.area.w() ||
|
enum { BYTES_PER_PIXEL = Virtio_gpu_device::BYTES_PER_PIXEL };
|
||||||
y > res.area.h() ||
|
|
||||||
w > res.area.w() ||
|
if (x > res.area.w() ||
|
||||||
h > res.area.h() ||
|
y > res.area.h() ||
|
||||||
x + w > res.area.w() ||
|
w > res.area.w() ||
|
||||||
|
h > res.area.h() ||
|
||||||
|
x + w > res.area.w() ||
|
||||||
y + h > res.area.h()) {
|
y + h > res.area.h()) {
|
||||||
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_PARAMETER);
|
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_PARAMETER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { BYTES_PER_PIXEL = Virtio_gpu_device::BYTES_PER_PIXEL };
|
|
||||||
response.write<Control_header::Type>(Control_header::Type::OK_NO_DATA);
|
response.write<Control_header::Type>(Control_header::Type::OK_NO_DATA);
|
||||||
|
|
||||||
void * src =
|
void * src =
|
||||||
@ -211,10 +218,10 @@ void Vmm::Virtio_gpu_control_request::_resource_flush()
|
|||||||
void * dst =
|
void * dst =
|
||||||
(void*)((addr_t)_device._fb_ds->local_addr<void>() +
|
(void*)((addr_t)_device._fb_ds->local_addr<void>() +
|
||||||
(_device._fb_mode.area.w() * y + x) * BYTES_PER_PIXEL);
|
(_device._fb_mode.area.w() * y + x) * BYTES_PER_PIXEL);
|
||||||
uint32_t line = res.area.w() * BYTES_PER_PIXEL;
|
uint32_t line_src = res.area.w() * BYTES_PER_PIXEL;
|
||||||
|
uint32_t line_dst = _device._fb_mode.area.w() * BYTES_PER_PIXEL;
|
||||||
blit(src, line, dst, line, w*BYTES_PER_PIXEL, h);
|
|
||||||
|
|
||||||
|
blit(src, line_src, dst, line_dst, w*BYTES_PER_PIXEL, h);
|
||||||
_device._gui.framebuffer()->refresh(x, y, w, h);
|
_device._gui.framebuffer()->refresh(x, y, w, h);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,6 @@ class Vmm::Virtio_gpu_device : public Virtio_device<Virtio_gpu_queue, 2>
|
|||||||
Constructible<Attached_dataspace> _fb_ds { };
|
Constructible<Attached_dataspace> _fb_ds { };
|
||||||
Framebuffer::Mode _fb_mode { _gui.mode() };
|
Framebuffer::Mode _fb_mode { _gui.mode() };
|
||||||
Gui::Session::View_handle _view = _gui.create_view();
|
Gui::Session::View_handle _view = _gui.create_view();
|
||||||
bool _mode_changed { true };
|
|
||||||
|
|
||||||
using Area = Genode::Area<>;
|
using Area = Genode::Area<>;
|
||||||
using Rect = Genode::Rect<>;
|
using Rect = Genode::Rect<>;
|
||||||
@ -390,25 +389,25 @@ class Vmm::Virtio_gpu_device : public Virtio_device<Virtio_gpu_queue, 2>
|
|||||||
enum {
|
enum {
|
||||||
EVENTS_READ = 0,
|
EVENTS_READ = 0,
|
||||||
EVENTS_CLEAR = 4,
|
EVENTS_CLEAR = 4,
|
||||||
SCANOUTS = 8 };
|
SCANOUTS = 8,
|
||||||
|
NUM_CAPSETS = 12
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Events { NONE = 0, DISPLAY = 1 };
|
||||||
|
|
||||||
Register read(Address_range & range, Cpu&) override
|
Register read(Address_range & range, Cpu&) override
|
||||||
{
|
{
|
||||||
if (range.start() == EVENTS_READ && range.size() == 4)
|
if (range.start() == EVENTS_READ)
|
||||||
return dev._mode_changed ? 1 : 0;
|
return DISPLAY;
|
||||||
|
|
||||||
/* we support no multi-head, just return 1 */
|
/* we support no multi-head, just return 1 */
|
||||||
if (range.start() == SCANOUTS && range.size() == 4)
|
if (range.start() == SCANOUTS)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(Address_range & range, Cpu&, Register v) override
|
void write(Address_range &, Cpu&, Register) override {}
|
||||||
{
|
|
||||||
if (range.start() == EVENTS_CLEAR && range.size() == 4 && v == 1)
|
|
||||||
dev._mode_changed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuration_area(Virtio_gpu_device & device)
|
Configuration_area(Virtio_gpu_device & device)
|
||||||
:
|
:
|
||||||
@ -420,21 +419,7 @@ class Vmm::Virtio_gpu_device : public Virtio_device<Virtio_gpu_queue, 2>
|
|||||||
void _mode_change()
|
void _mode_change()
|
||||||
{
|
{
|
||||||
Genode::Mutex::Guard guard(_mutex);
|
Genode::Mutex::Guard guard(_mutex);
|
||||||
|
_config_notification();
|
||||||
_fb_mode = _gui.mode();
|
|
||||||
|
|
||||||
_gui.buffer(_fb_mode, false);
|
|
||||||
|
|
||||||
if (_fb_mode.area.count() > 0)
|
|
||||||
_fb_ds.construct(_env.rm(),
|
|
||||||
_gui.framebuffer()->dataspace());
|
|
||||||
|
|
||||||
using Command = Gui::Session::Command;
|
|
||||||
_gui.enqueue<Command::Geometry>(_view, Rect(Point(0, 0), _fb_mode.area));
|
|
||||||
_gui.enqueue<Command::To_front>(_view, Gui::Session::View_handle());
|
|
||||||
_gui.execute();
|
|
||||||
|
|
||||||
_mode_changed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _notify(unsigned idx) override
|
void _notify(unsigned idx) override
|
||||||
@ -466,13 +451,30 @@ class Vmm::Virtio_gpu_device : public Virtio_device<Virtio_gpu_queue, 2>
|
|||||||
_handler(cpu, env.ep(), *this, &Virtio_gpu_device::_mode_change)
|
_handler(cpu, env.ep(), *this, &Virtio_gpu_device::_mode_change)
|
||||||
{
|
{
|
||||||
_gui.mode_sigh(_handler);
|
_gui.mode_sigh(_handler);
|
||||||
_mode_change();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void buffer_notification()
|
void buffer_notification()
|
||||||
{
|
{
|
||||||
_buffer_notification();
|
_buffer_notification();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Framebuffer::Mode resize()
|
||||||
|
{
|
||||||
|
_fb_ds.destruct();
|
||||||
|
|
||||||
|
_fb_mode = _gui.mode();
|
||||||
|
_gui.buffer(_fb_mode, false);
|
||||||
|
|
||||||
|
if (_fb_mode.area.count() > 0)
|
||||||
|
_fb_ds.construct(_env.rm(),
|
||||||
|
_gui.framebuffer()->dataspace());
|
||||||
|
|
||||||
|
using Command = Gui::Session::Command;
|
||||||
|
_gui.enqueue<Command::Geometry>(_view, Rect(Point(0, 0), _fb_mode.area));
|
||||||
|
_gui.enqueue<Command::To_front>(_view, Gui::Session::View_handle());
|
||||||
|
_gui.execute();
|
||||||
|
return _gui.mode();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _VIRTIO_GPU_H_ */
|
#endif /* _VIRTIO_GPU_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user