Skip to content

Commit

Permalink
intel/display: handle configuration with no merge
Browse files Browse the repository at this point in the history
node at all. Fixes a regression. W/o the commit, discrete only
configurations may not work properly, e.g. not showing content on
any display.

Issue genodelabs#5415
  • Loading branch information
alex-ab committed Jan 14, 2025
1 parent c5fe0c4 commit 1bf59c6
Showing 1 changed file with 42 additions and 36 deletions.
78 changes: 42 additions & 36 deletions repos/pc/src/driver/framebuffer/intel/pc/lx_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,28 +463,24 @@ static struct drm_display_mode * best_mode(struct genode_mode const * const
}


static void reconfigure(struct drm_client_dev * const dev)
{
static struct drm_mode_create_dumb * gem_mirror = NULL;
static struct drm_mode_fb_cmd2 * mirror_fb_cmd = NULL;

struct drm_connector_list_iter conn_iter;
struct drm_connector * connector = NULL;
struct meta_data_mirror {
struct fb_info info;
struct drm_display_mode mode;
unsigned width_mm;
unsigned height_mm;
bool report;
};

struct drm_display_mode mirror_force = {};
struct drm_display_mode mirror_compound = {};
struct drm_display_mode mirror_minimum = {};
struct drm_display_mode mirror_fb = {};

struct {
struct fb_info info;
unsigned width_mm;
unsigned height_mm;
bool report;
} mirror = { { }, 0, 0, false };
static void handle_mirror(struct drm_client_dev * const dev,
struct meta_data_mirror * const mirror)
{
struct drm_display_mode mirror_force = {};
struct drm_display_mode mirror_compound = {};
struct drm_display_mode mirror_minimum = {};

gem_mirror = &states[CONNECTOR_ID_MIRROR].fb_dumb;
mirror_fb_cmd = &states[CONNECTOR_ID_MIRROR].fb_cmd;
struct drm_mode_create_dumb * gem_mirror = &states[CONNECTOR_ID_MIRROR].fb_dumb;
struct drm_mode_fb_cmd2 * mirror_fb_cmd = &states[CONNECTOR_ID_MIRROR].fb_cmd;

if (!dev || !dev->dev || !gem_mirror || !mirror_fb_cmd)
return;
Expand All @@ -504,9 +500,9 @@ static void reconfigure(struct drm_client_dev * const dev)
}

if (mode_larger(&mirror_compound, &mirror_minimum))
mirror_fb = mirror_compound;
mirror->mode = mirror_compound;
else
mirror_fb = mirror_minimum;
mirror->mode = mirror_minimum;

{
struct state * state_mirror = &states[CONNECTOR_ID_MIRROR];
Expand All @@ -516,12 +512,12 @@ static void reconfigure(struct drm_client_dev * const dev)
gem_mirror,
mirror_fb_cmd,
&resized,
mirror_fb.hdisplay,
mirror_fb.vdisplay);
mirror->mode.hdisplay,
mirror->mode.vdisplay);

if (err) {
printk("setting up mirrored framebuffer of %ux%u failed - error=%d\n",
mirror_fb.hdisplay, mirror_fb.vdisplay, err);
mirror->mode.hdisplay, mirror->mode.vdisplay, err);

return;
}
Expand All @@ -530,7 +526,7 @@ static void reconfigure(struct drm_client_dev * const dev)
printk("mirror: compound %ux%u force=%ux%u fb=%ux%u\n",
mirror_compound.hdisplay, mirror_compound.vdisplay,
mirror_force.hdisplay, mirror_force.vdisplay,
mirror_fb.hdisplay, mirror_fb.vdisplay);
mirror->mode.hdisplay, mirror->mode.vdisplay);
}

/* if mirrored fb changed, drop reference and get new framebuffer */
Expand All @@ -542,19 +538,28 @@ static void reconfigure(struct drm_client_dev * const dev)
mirror_fb_cmd->fb_id);
}

mirror.info.var.xres = mirror_fb.hdisplay;
mirror.info.var.yres = mirror_fb.vdisplay;
mirror.info.var.xres_virtual = mirror_force.hdisplay ? : mirror_compound.hdisplay;
mirror.info.var.yres_virtual = mirror_force.vdisplay ? : mirror_compound.vdisplay;
mirror.info.node = CONNECTOR_ID_MIRROR;
mirror.info.par = "mirror_capture";
mirror->info.var.xres = mirror->mode.hdisplay;
mirror->info.var.yres = mirror->mode.vdisplay;
mirror->info.var.xres_virtual = mirror_force.hdisplay ? : mirror_compound.hdisplay;
mirror->info.var.yres_virtual = mirror_force.vdisplay ? : mirror_compound.vdisplay;
mirror->info.node = CONNECTOR_ID_MIRROR;
mirror->info.par = "mirror_capture";
}
}


/* without fb handle created by check_resize_fb we can't proceed */
if (!mirror_fb_cmd->fb_id) {
printk("%s:%u no mirror fb id\n", __func__, __LINE__);
static void reconfigure(struct drm_client_dev * const dev)
{
struct drm_connector_list_iter conn_iter;
struct drm_connector * connector = NULL;

struct meta_data_mirror mirror = {};

if (!dev || !dev->dev)
return;
}

/* handle mirror/merge connectors */
handle_mirror(dev, &mirror);

drm_connector_list_iter_begin(dev_client->dev, &conn_iter);
drm_client_for_each_connector_iter(connector, &conn_iter) {
Expand Down Expand Up @@ -585,7 +590,7 @@ static void reconfigure(struct drm_client_dev * const dev)
}

/* lookup next mode */
mode = best_mode(&conf_mode, connector, &mirror_fb, &no_match, &mode_id);
mode = best_mode(&conf_mode, connector, &mirror.mode, &no_match, &mode_id);

/* reduce flickering if in same state */
same_state = conf_mode.mirror == state->mirrored &&
Expand Down Expand Up @@ -647,6 +652,7 @@ static void reconfigure(struct drm_client_dev * const dev)
}

if (conf_mode.mirror) {
struct drm_mode_fb_cmd2 * mirror_fb_cmd = &states[CONNECTOR_ID_MIRROR].fb_cmd;
/* get new fb reference for mirrored fb */
state->fbs = drm_framebuffer_lookup(dev->dev, dev->file,
mirror_fb_cmd->fb_id);
Expand Down

0 comments on commit 1bf59c6

Please sign in to comment.