mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
parent
50cc52a091
commit
458458b65f
@ -33,10 +33,12 @@ struct genode_mode {
|
||||
char name[32];
|
||||
};
|
||||
|
||||
int lx_emul_i915_blit(unsigned);
|
||||
int lx_emul_i915_blit(unsigned const connector_id, char const may_sleep);
|
||||
void lx_emul_i915_wakeup(unsigned connector_id);
|
||||
void lx_emul_i915_report_discrete(void * genode_xml);
|
||||
void lx_emul_i915_report_non_discrete(void * genode_xml);
|
||||
void lx_emul_i915_hotplug_connector(void);
|
||||
|
||||
void lx_emul_i915_report_connector(void * lx_data, void * genode_xml,
|
||||
char const *name, char connected,
|
||||
unsigned brightness,
|
||||
|
@ -837,25 +837,67 @@ static void mark_framebuffer_dirty(struct drm_framebuffer * const fb)
|
||||
}
|
||||
|
||||
|
||||
/* track per connector (16 max) the empty capture attempts before stopping */
|
||||
enum { CAPTURE_RATE_MS = 10, ATTEMPTS_BEFORE_STOP = 7 };
|
||||
static unsigned unchanged[16] = { };
|
||||
|
||||
void lx_emul_i915_wakeup(unsigned const connector_id)
|
||||
{
|
||||
bool const valid_id = connector_id < sizeof(unchanged) / sizeof(*unchanged);
|
||||
|
||||
if (!valid_id) {
|
||||
printk("%s: connector id invalid %d\n", __func__, connector_id);
|
||||
return;
|
||||
}
|
||||
|
||||
unchanged[connector_id] = 0;
|
||||
|
||||
/* wake potential sleeping update task */
|
||||
lx_emul_task_unblock(lx_update_task);
|
||||
}
|
||||
|
||||
|
||||
static int update_content(void *)
|
||||
{
|
||||
while (true) {
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_connector *connector = NULL;
|
||||
struct drm_device const *dev = dev_client->dev;
|
||||
struct drm_connector *connector = NULL;
|
||||
struct drm_device const *dev = dev_client->dev;
|
||||
bool block_task = true;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_client_for_each_connector_iter(connector, &conn_iter) {
|
||||
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
struct drm_framebuffer *fb = NULL;
|
||||
int err = -1;
|
||||
|
||||
int err = -1;
|
||||
bool may_sleep = false;
|
||||
bool const valid_id = connector->index < sizeof(unchanged) / sizeof(*unchanged);
|
||||
|
||||
if (connector->status != connector_status_connected)
|
||||
continue;
|
||||
|
||||
if (!lx_emul_i915_blit(connector->index))
|
||||
if (valid_id) {
|
||||
unchanged[connector->index] ++;
|
||||
|
||||
if (unchanged[connector->index] > ATTEMPTS_BEFORE_STOP)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
printk("%s: connector id invalid %d\n", __func__, connector->index);
|
||||
|
||||
block_task = false;
|
||||
|
||||
if (valid_id)
|
||||
may_sleep = unchanged[connector->index] >= ATTEMPTS_BEFORE_STOP;
|
||||
|
||||
if (!lx_emul_i915_blit(connector->index, may_sleep))
|
||||
continue;
|
||||
|
||||
if (valid_id)
|
||||
unchanged[connector->index] = 0;
|
||||
|
||||
if (!connector->state || !connector->state->crtc)
|
||||
continue;
|
||||
|
||||
@ -872,8 +914,11 @@ static int update_content(void *)
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
|
||||
/* schedule_timeout(jiffes) or hrtimer or msleep */
|
||||
msleep(20);
|
||||
if (block_task)
|
||||
lx_emul_task_schedule(true /* block task */);
|
||||
else
|
||||
/* schedule_timeout(jiffes) or hrtimer or msleep */
|
||||
msleep(CAPTURE_RATE_MS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -67,9 +67,8 @@ struct Framebuffer::Driver
|
||||
using Space = Id_space<Connector>;
|
||||
using Id = Space::Id;
|
||||
|
||||
Space::Element id_element;
|
||||
|
||||
Connector(Space &space, Id id) : id_element(*this, space, id) { }
|
||||
Space::Element id_element;
|
||||
Signal_handler<Connector> capture_wakeup;
|
||||
|
||||
addr_t base { };
|
||||
Capture::Area size { };
|
||||
@ -78,11 +77,23 @@ struct Framebuffer::Driver
|
||||
|
||||
Constructible<Capture::Connection> capture { };
|
||||
Constructible<Capture::Connection::Screen> screen { };
|
||||
|
||||
Connector(Env &env, Space &space, Id id)
|
||||
:
|
||||
id_element(*this, space, id),
|
||||
capture_wakeup(env.ep(), *this, &Connector::wakeup_handler)
|
||||
{ }
|
||||
|
||||
void wakeup_handler()
|
||||
{
|
||||
lx_emul_i915_wakeup(unsigned(id_element.id().value));
|
||||
Lx_kit::env().scheduler.execute();
|
||||
}
|
||||
};
|
||||
|
||||
Connector::Space ids { };
|
||||
|
||||
bool capture(Connector::Space &ids, Connector::Id const &id)
|
||||
bool capture(Connector::Space &ids, Connector::Id const &id, bool const may_stop)
|
||||
{
|
||||
using Pixel = Capture::Pixel;
|
||||
|
||||
@ -109,6 +120,10 @@ struct Framebuffer::Driver
|
||||
dirty = true;
|
||||
});
|
||||
});
|
||||
|
||||
if (!dirty && may_stop)
|
||||
connector.capture->capture_stopped();
|
||||
|
||||
}, [&](){ /* unknown connector id */ });
|
||||
|
||||
return dirty;
|
||||
@ -136,6 +151,8 @@ struct Framebuffer::Driver
|
||||
Capture::Connection::Screen::Attr attr = { .px = conn.size, .mm = conn.size_mm };
|
||||
conn.capture.construct(env, label);
|
||||
conn.screen .construct(*conn.capture, env.rm(), attr);
|
||||
|
||||
conn.capture->wakeup_sigh(conn.capture_wakeup);
|
||||
} else {
|
||||
conn.screen .destruct();
|
||||
conn.capture.destruct();
|
||||
@ -450,7 +467,9 @@ void lx_emul_i915_framebuffer_ready(unsigned const connector_id,
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
new (drv.heap) Connector (drv.ids, id);
|
||||
new (drv.heap) Connector (env, drv.ids, id);
|
||||
|
||||
lx_emul_i915_wakeup(unsigned(id.value));
|
||||
});
|
||||
|
||||
drv.ids.apply<Connector>(id, [&](Connector &conn) {
|
||||
@ -549,13 +568,13 @@ void lx_emul_i915_report_modes(void * genode_xml, struct genode_mode *mode)
|
||||
}
|
||||
|
||||
|
||||
int lx_emul_i915_blit(unsigned connector_id)
|
||||
int lx_emul_i915_blit(unsigned const connector_id, char const may_stop)
|
||||
{
|
||||
auto &drv = driver(Lx_kit::env().env);
|
||||
|
||||
auto const id = Framebuffer::Driver::Connector::Id { connector_id };
|
||||
|
||||
return drv.capture(drv.ids, id);
|
||||
return drv.capture(drv.ids, id, may_stop);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user