Cache modesetting data and just do drmModeSetCrtc on vt enter.
This commit is contained in:
parent
38ccd3a23e
commit
2c875bd31e
@ -77,11 +77,9 @@ struct egl_compositor {
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
EGLConfig config;
|
||||
uint32_t fb_id;
|
||||
struct wl_display *wl_display;
|
||||
int gem_fd;
|
||||
int tty_fd;
|
||||
int width, height;
|
||||
int width, height, stride;
|
||||
struct egl_surface *background;
|
||||
struct egl_surface *overlay;
|
||||
double overlay_y, overlay_target, overlay_previous;
|
||||
@ -92,6 +90,12 @@ struct egl_compositor {
|
||||
struct wl_event_source *enter_vt_source;
|
||||
struct wl_event_source *leave_vt_source;
|
||||
|
||||
/* Modesetting info. */
|
||||
struct drm_mode_modeinfo *mode;
|
||||
uint32_t fb_id;
|
||||
uint32_t crtc_id;
|
||||
uint32_t connector_id;
|
||||
|
||||
/* Repaint state. */
|
||||
struct wl_event_source *timer_source;
|
||||
int repaint_needed;
|
||||
@ -866,7 +870,7 @@ egl_device_get_position(struct egl_input_device *device, int32_t *x, int32_t *y)
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
create_frontbuffer(int fd, int *width, int *height, int *stride, uint32_t *fb_id)
|
||||
create_frontbuffer(struct egl_compositor *ec)
|
||||
{
|
||||
drmModeConnector *connector;
|
||||
drmModeRes *resources;
|
||||
@ -874,8 +878,9 @@ create_frontbuffer(int fd, int *width, int *height, int *stride, uint32_t *fb_id
|
||||
struct drm_mode_modeinfo *mode;
|
||||
struct drm_i915_gem_create create;
|
||||
struct drm_gem_flink flink;
|
||||
int i, ret;
|
||||
int i, ret, fd;
|
||||
|
||||
fd = eglGetDisplayFD(ec->display);
|
||||
resources = drmModeGetResources(fd);
|
||||
if (!resources) {
|
||||
fprintf(stderr, "drmModeGetResources failed\n");
|
||||
@ -921,13 +926,13 @@ create_frontbuffer(int fd, int *width, int *height, int *stride, uint32_t *fb_id
|
||||
}
|
||||
|
||||
ret = drmModeAddFB(fd, mode->hdisplay, mode->vdisplay,
|
||||
32, 32, mode->hdisplay * 4, create.handle, fb_id);
|
||||
32, 32, mode->hdisplay * 4, create.handle, &ec->fb_id);
|
||||
if (ret) {
|
||||
fprintf(stderr, "failed to add fb: %m\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = drmModeSetCrtc(fd, encoder->crtc_id, *fb_id, 0, 0,
|
||||
ret = drmModeSetCrtc(fd, encoder->crtc_id, ec->fb_id, 0, 0,
|
||||
&connector->connector_id, 1, mode);
|
||||
if (ret) {
|
||||
fprintf(stderr, "failed to set mode: %m\n");
|
||||
@ -940,9 +945,12 @@ create_frontbuffer(int fd, int *width, int *height, int *stride, uint32_t *fb_id
|
||||
return 0;
|
||||
}
|
||||
|
||||
*width = mode->hdisplay;
|
||||
*height = mode->vdisplay;
|
||||
*stride = mode->hdisplay * 4;
|
||||
ec->crtc_id = encoder->crtc_id;
|
||||
ec->connector_id = connector->connector_id;
|
||||
ec->mode = mode;
|
||||
ec->width = mode->hdisplay;
|
||||
ec->height = mode->vdisplay;
|
||||
ec->stride = mode->hdisplay * 4;
|
||||
|
||||
return flink.name;
|
||||
}
|
||||
@ -1046,61 +1054,17 @@ static const GOptionEntry option_entries[] = {
|
||||
static void on_enter_vt(int signal_number, void *data)
|
||||
{
|
||||
struct egl_compositor *ec = data;
|
||||
|
||||
drmModeConnector *connector;
|
||||
drmModeRes *resources;
|
||||
drmModeEncoder *encoder;
|
||||
struct drm_mode_modeinfo *mode;
|
||||
int i, ret;
|
||||
int fd;
|
||||
int ret, fd;
|
||||
|
||||
ioctl(ec->tty_fd, VT_RELDISP, VT_ACKACQ);
|
||||
|
||||
fd = ec->gem_fd;
|
||||
resources = drmModeGetResources(fd);
|
||||
if (!resources) {
|
||||
fprintf(stderr, "drmModeGetResources failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < resources->count_connectors; i++) {
|
||||
connector = drmModeGetConnector(fd, resources->connectors[i]);
|
||||
if (connector == NULL)
|
||||
continue;
|
||||
|
||||
if (connector->connection == DRM_MODE_CONNECTED &&
|
||||
connector->count_modes > 0)
|
||||
break;
|
||||
|
||||
drmModeFreeConnector(connector);
|
||||
}
|
||||
|
||||
if (i == resources->count_connectors) {
|
||||
fprintf(stderr, "No currently active connector found.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mode = &connector->modes[0];
|
||||
|
||||
for (i = 0; i < resources->count_encoders; i++) {
|
||||
encoder = drmModeGetEncoder(fd, resources->encoders[i]);
|
||||
|
||||
if (encoder == NULL)
|
||||
continue;
|
||||
|
||||
if (encoder->encoder_id == connector->encoder_id)
|
||||
break;
|
||||
|
||||
drmModeFreeEncoder(encoder);
|
||||
}
|
||||
|
||||
ret = drmModeSetCrtc(fd, encoder->crtc_id, ec->fb_id, 0, 0,
|
||||
&connector->connector_id, 1, mode);
|
||||
fd = eglGetDisplayFD(ec->display);
|
||||
ret = drmModeSetCrtc(fd, ec->crtc_id, ec->fb_id, 0, 0,
|
||||
&ec->connector_id, 1, ec->mode);
|
||||
if (ret) {
|
||||
fprintf(stderr, "failed to set mode: %m\n");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void on_leave_vt(int signal_number, void *data)
|
||||
@ -1138,7 +1102,7 @@ egl_compositor_create(struct wl_display *display)
|
||||
struct egl_compositor *ec;
|
||||
struct screenshooter *shooter;
|
||||
uint32_t fb_name;
|
||||
int i, stride;
|
||||
int i;
|
||||
struct wl_event_loop *loop;
|
||||
const static EGLint attribs[] =
|
||||
{ EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
|
||||
@ -1163,10 +1127,9 @@ egl_compositor_create(struct wl_display *display)
|
||||
if (pick_config(ec))
|
||||
return NULL;
|
||||
|
||||
fb_name = create_frontbuffer(eglGetDisplayFD(ec->display),
|
||||
&ec->width, &ec->height, &stride, &ec->fb_id);
|
||||
fb_name = create_frontbuffer(ec);
|
||||
ec->surface = eglCreateSurfaceForName(ec->display, ec->config,
|
||||
fb_name, ec->width, ec->height, stride, attribs);
|
||||
fb_name, ec->width, ec->height, ec->stride, attribs);
|
||||
if (ec->surface == NULL) {
|
||||
fprintf(stderr, "failed to create surface\n");
|
||||
return NULL;
|
||||
@ -1205,12 +1168,6 @@ egl_compositor_create(struct wl_display *display)
|
||||
ec->overlay_target = ec->height;
|
||||
ec->overlay_previous = ec->height;
|
||||
|
||||
ec->gem_fd = open(gem_device, O_RDWR);
|
||||
if (ec->gem_fd < 0) {
|
||||
fprintf(stderr, "failed to open drm device\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shooter = screenshooter_create(ec);
|
||||
wl_display_add_object(display, &shooter->base);
|
||||
wl_display_add_global(display, &shooter->base);
|
||||
|
Loading…
Reference in New Issue
Block a user