Cache modesetting data and just do drmModeSetCrtc on vt enter.

This commit is contained in:
Kristian Høgsberg 2008-12-19 10:34:02 -05:00
parent 38ccd3a23e
commit 2c875bd31e
1 changed files with 25 additions and 68 deletions

View File

@ -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);