diff --git a/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h b/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h
index 2ae68b1228..3eb8eb5444 100644
--- a/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h
+++ b/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h
@@ -32,6 +32,7 @@ struct genode_mode {
char name[32];
};
+int lx_emul_i915_blit(void);
void lx_emul_i915_report(void * genode_xml);
void lx_emul_i915_hotplug_connector(void);
void lx_emul_i915_report_connector(void * lx_data, void * genode_xml,
diff --git a/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c b/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c
index bae52778fe..4830133ff1 100644
--- a/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c
+++ b/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c
@@ -504,8 +504,12 @@ void framebuffer_dirty(void)
static int update_content(void *)
{
while (true) {
- framebuffer_dirty();
- lx_emul_task_schedule(true /* block task */);
+
+ if (lx_emul_i915_blit())
+ framebuffer_dirty();
+
+ /* schedule_timeout(jiffes) or hrtimer or msleep */
+ msleep(20);
}
return 0;
diff --git a/repos/pc/src/driver/framebuffer/intel/pc/main.cc b/repos/pc/src/driver/framebuffer/intel/pc/main.cc
index 841cd5d9ee..aca7b0fbba 100644
--- a/repos/pc/src/driver/framebuffer/intel/pc/main.cc
+++ b/repos/pc/src/driver/framebuffer/intel/pc/main.cc
@@ -13,7 +13,6 @@
#include
#include
-#include
#include
#include
#include
@@ -33,7 +32,6 @@ extern "C" {
extern struct task_struct * lx_user_task;
-extern struct task_struct * lx_update_task;
namespace Framebuffer {
@@ -47,15 +45,12 @@ struct Framebuffer::Driver
using Attached_rom_system = Constructible;
Env &env;
- Timer::Connection timer { env };
Attached_rom_dataspace config { env, "config" };
Attached_rom_system system { };
Expanding_reporter reporter { env, "connectors", "connectors" };
Signal_handler config_handler { env.ep(), *this,
&Driver::config_update };
- Signal_handler timer_handler { env.ep(), *this,
- &Driver::handle_timer };
Signal_handler scheduler_handler { env.ep(), *this,
&Driver::handle_scheduler };
Signal_handler system_handler { env.ep(), *this,
@@ -84,17 +79,29 @@ struct Framebuffer::Driver
public:
- void paint()
+ bool paint()
{
using Pixel = Capture::Pixel;
- Surface surface((Pixel*)_base, _size_phys);
- _captured_screen.apply_to_surface(surface);
- if (!lx_update_task)
- return;
+ bool dirty = false;
- lx_emul_task_unblock(lx_update_task);
- Lx_kit::env().scheduler.execute();
+ _captured_screen.with_texture([&] (Texture const &texture) {
+
+ auto const affected = _capture.capture_at(Capture::Point(0, 0));
+
+ affected.for_each_rect([&] (Capture::Rect const rect) {
+
+ Surface surface((Pixel*)_base, _size_phys);
+
+ surface.clip(rect);
+
+ Blit_painter::paint(surface, texture, Capture::Point(0, 0));
+
+ dirty = true;
+ });
+ });
+
+ return dirty;
}
Fb(Env & env, void * base, Capture::Area size,
@@ -121,11 +128,6 @@ struct Framebuffer::Driver
void generate_report();
void lookup_config(char const *, struct genode_mode &mode);
- void handle_timer()
- {
- if (fb.constructed()) { fb->paint(); }
- }
-
void handle_scheduler()
{
Lx_kit::env().scheduler.execute();
@@ -164,9 +166,6 @@ struct Framebuffer::Driver
log("--- Intel framebuffer driver started ---");
lx_emul_start_kernel(nullptr);
-
- timer.sigh(timer_handler);
- timer.trigger_periodic(20*1000);
}
bool apply_config_on_hotplug() const
@@ -467,6 +466,17 @@ void lx_emul_i915_report_modes(void * genode_xml, struct genode_mode *mode)
}
+int lx_emul_i915_blit()
+{
+ auto &drv = driver(Lx_kit::env().env);
+
+ if (!drv.fb.constructed())
+ return false;
+
+ return drv.fb->paint();
+}
+
+
void lx_emul_i915_connector_config(char * name, struct genode_mode * mode)
{
if (!mode || !name)