compositor-drm: Free output on error in create_output_for_connector

We currently simply return -1 on error in create_output_for_connector. This
correctly frees the output and all modes when we fail to avoid memory leaks.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
dev
David Herrmann 13 years ago committed by Kristian Høgsberg
parent eb8bed5c73
commit 0f0d54e5c5
  1. 34
      compositor/compositor-drm.c

@ -427,7 +427,7 @@ create_output_for_connector(struct drm_compositor *ec,
int x, int y) int x, int y)
{ {
struct drm_output *output; struct drm_output *output;
struct drm_mode *drm_mode; struct drm_mode *drm_mode, *next;
drmModeEncoder *encoder; drmModeEncoder *encoder;
int i, ret; int i, ret;
unsigned handle, stride; unsigned handle, stride;
@ -467,11 +467,19 @@ create_output_for_connector(struct drm_compositor *ec,
ec->connector_allocator |= (1 << output->connector_id); ec->connector_allocator |= (1 << output->connector_id);
output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id); output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
drmModeFreeEncoder(encoder);
for (i = 0; i < connector->count_modes; i++) {
ret = drm_output_add_mode(output, &connector->modes[i]);
if (ret)
goto err_free;
}
for (i = 0; i < connector->count_modes; i++) if (connector->count_modes == 0) {
drm_output_add_mode(output, &connector->modes[i]); ret = drm_output_add_mode(output, &builtin_1024x768);
if (connector->count_modes == 0) if (ret)
drm_output_add_mode(output, &builtin_1024x768); goto err_free;
}
drm_mode = container_of(output->base.mode_list.next, drm_mode = container_of(output->base.mode_list.next,
struct drm_mode, base.link); struct drm_mode, base.link);
@ -479,8 +487,6 @@ create_output_for_connector(struct drm_compositor *ec,
drm_mode->base.flags = drm_mode->base.flags =
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
drmModeFreeEncoder(encoder);
glGenRenderbuffers(2, output->rbo); glGenRenderbuffers(2, output->rbo);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
glBindRenderbuffer(GL_RENDERBUFFER, output->rbo[i]); glBindRenderbuffer(GL_RENDERBUFFER, output->rbo[i]);
@ -541,6 +547,20 @@ create_output_for_connector(struct drm_compositor *ec,
output->base.destroy = drm_output_destroy; output->base.destroy = drm_output_destroy;
return 0; return 0;
err_free:
wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
base.link) {
wl_list_remove(&drm_mode->base.link);
free(drm_mode);
}
drmModeFreeCrtc(output->original_crtc);
ec->crtc_allocator &= ~(1 << output->crtc_id);
ec->connector_allocator &= ~(1 << output->connector_id);
free(output);
return -1;
} }
static int static int

Loading…
Cancel
Save