intel/display: make effective use of PSR

- only mark framebuffer dirty if necessary
  -> gives the hardware chance to save longer power
- remove extra timer connection on Genode component side
  -> use Linux time primitives

Issue #5339
This commit is contained in:
Alexander Boettcher 2024-08-26 17:02:28 +02:00 committed by Norman Feske
parent 0414e4929f
commit f147a1220e
3 changed files with 37 additions and 22 deletions

View File

@ -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,

View File

@ -504,8 +504,12 @@ void framebuffer_dirty(void)
static int update_content(void *)
{
while (true) {
if (lx_emul_i915_blit())
framebuffer_dirty();
lx_emul_task_schedule(true /* block task */);
/* schedule_timeout(jiffes) or hrtimer or msleep */
msleep(20);
}
return 0;

View File

@ -13,7 +13,6 @@
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <timer_session/connection.h>
#include <capture_session/connection.h>
#include <os/pixel_rgb888.h>
#include <os/reporter.h>
@ -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<Attached_rom_dataspace>;
Env &env;
Timer::Connection timer { env };
Attached_rom_dataspace config { env, "config" };
Attached_rom_system system { };
Expanding_reporter reporter { env, "connectors", "connectors" };
Signal_handler<Driver> config_handler { env.ep(), *this,
&Driver::config_update };
Signal_handler<Driver> timer_handler { env.ep(), *this,
&Driver::handle_timer };
Signal_handler<Driver> scheduler_handler { env.ep(), *this,
&Driver::handle_scheduler };
Signal_handler<Driver> system_handler { env.ep(), *this,
@ -84,17 +79,29 @@ struct Framebuffer::Driver
public:
void paint()
bool paint()
{
using Pixel = Capture::Pixel;
bool dirty = false;
_captured_screen.with_texture([&] (Texture<Pixel> const &texture) {
auto const affected = _capture.capture_at(Capture::Point(0, 0));
affected.for_each_rect([&] (Capture::Rect const rect) {
Surface<Pixel> surface((Pixel*)_base, _size_phys);
_captured_screen.apply_to_surface(surface);
if (!lx_update_task)
return;
surface.clip(rect);
lx_emul_task_unblock(lx_update_task);
Lx_kit::env().scheduler.execute();
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)