Clean up outputs on exit

This commit is contained in:
Drew DeVault 2017-05-31 16:17:04 -04:00
parent 579909a368
commit c7f6981d9c
6 changed files with 34 additions and 9 deletions

View file

@ -33,7 +33,6 @@ bool wlr_backend_init(struct wlr_backend *backend) {
void wlr_backend_destroy(struct wlr_backend *backend) { void wlr_backend_destroy(struct wlr_backend *backend) {
backend->impl->destroy(backend->state); backend->impl->destroy(backend->state);
// TODO: free outputs
free(backend); free(backend);
} }

View file

@ -6,6 +6,7 @@
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/session.h> #include <wlr/session.h>
#include <wlr/wayland.h>
#include <wlr/common/list.h> #include <wlr/common/list.h>
#include "backend.h" #include "backend.h"
@ -23,7 +24,10 @@ static void wlr_drm_backend_destroy(struct wlr_backend_state *state) {
if (!state) { if (!state) {
return; return;
} }
// TODO: free outputs in shared backend code for (size_t i = 0; state->outputs && i < state->outputs->length; ++i) {
struct wlr_output_state *output = state->outputs->items[i];
wlr_output_destroy(output->wlr_output);
}
wlr_drm_renderer_free(&state->renderer); wlr_drm_renderer_free(&state->renderer);
wlr_udev_free(&state->udev); wlr_udev_free(&state->udev);
wlr_session_close_file(state->session, state->fd); wlr_session_close_file(state->session, state->fd);

View file

@ -103,8 +103,13 @@ static void wlr_drm_output_begin(struct wlr_output_state *output) {
static void wlr_drm_output_end(struct wlr_output_state *output) { static void wlr_drm_output_end(struct wlr_output_state *output) {
struct wlr_drm_renderer *renderer = output->renderer; struct wlr_drm_renderer *renderer = output->renderer;
eglSwapBuffers(renderer->egl.display, output->egl); if (!eglSwapBuffers(renderer->egl.display, output->egl)) {
return;
}
struct gbm_bo *bo = gbm_surface_lock_front_buffer(output->gbm); struct gbm_bo *bo = gbm_surface_lock_front_buffer(output->gbm);
if (!bo) {
return;
}
uint32_t fb_id = get_fb_for_bo(renderer->fd, bo); uint32_t fb_id = get_fb_for_bo(renderer->fd, bo);
drmModePageFlip(renderer->fd, output->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output); drmModePageFlip(renderer->fd, output->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output);
gbm_surface_release_buffer(output->gbm, bo); gbm_surface_release_buffer(output->gbm, bo);
@ -399,7 +404,6 @@ void wlr_drm_scan_connectors(struct wlr_backend_state *state) {
conn->connection != DRM_MODE_CONNECTED) { conn->connection != DRM_MODE_CONNECTED) {
wlr_log(L_INFO, "'%s' disconnected", output->name); wlr_log(L_INFO, "'%s' disconnected", output->name);
// TODO: Destroy
wlr_drm_output_cleanup(output, false); wlr_drm_output_cleanup(output, false);
} }
@ -459,6 +463,11 @@ void wlr_drm_output_cleanup(struct wlr_output_state *output, bool restore) {
switch (output->state) { switch (output->state) {
case DRM_OUTPUT_CONNECTED: case DRM_OUTPUT_CONNECTED:
output->state = DRM_OUTPUT_DISCONNECTED;
if (restore) {
restore_output(output, renderer->fd);
restore = false;
}
eglDestroySurface(renderer->egl.display, output->egl); eglDestroySurface(renderer->egl.display, output->egl);
gbm_surface_destroy(output->gbm); gbm_surface_destroy(output->gbm);
output->egl = EGL_NO_SURFACE; output->egl = EGL_NO_SURFACE;
@ -475,5 +484,4 @@ void wlr_drm_output_cleanup(struct wlr_output_state *output, bool restore) {
case DRM_OUTPUT_DISCONNECTED: case DRM_OUTPUT_DISCONNECTED:
break; break;
} }
// TODO: free wlr_output
} }

View file

@ -66,8 +66,21 @@ void output_add(struct wl_listener *listener, void *data) {
void output_remove(struct wl_listener *listener, void *data) { void output_remove(struct wl_listener *listener, void *data) {
struct wlr_output *output = data; struct wlr_output *output = data;
fprintf(stderr, "Output '%s' removed\n", output->name); struct output_state *ostate = NULL;
// TODO: remove signal from state->output_frame struct state *state = wl_container_of(listener, state, output_remove);
size_t i;
for (i = 0; i < state->outputs->length; ++i) {
struct output_state *_ostate = state->outputs->items[i];
if (_ostate->output == output) {
ostate = _ostate;
break;
}
}
if (!ostate) {
return; // We are unfamiliar with this output
}
list_del(state->outputs, i);
wl_list_remove(&ostate->frame.link);
} }
int timer_done(void *data) { int timer_done(void *data) {

View file

@ -41,5 +41,6 @@ struct wlr_output {
bool wlr_output_set_mode(struct wlr_output *output, struct wlr_output_mode *mode); bool wlr_output_set_mode(struct wlr_output *output, struct wlr_output_mode *mode);
void wlr_output_enable(struct wlr_output *output, bool enable); void wlr_output_enable(struct wlr_output *output, bool enable);
void wlr_output_destroy(struct wlr_output *output);
#endif #endif

View file

@ -14,15 +14,15 @@ struct wlr_output *wlr_output_create(struct wlr_output_impl *impl,
return output; return output;
} }
void wlr_output_free(struct wlr_output *output) { void wlr_output_destroy(struct wlr_output *output) {
if (!output) return; if (!output) return;
output->impl->destroy(output->state);
if (output->make) free(output->make); if (output->make) free(output->make);
if (output->model) free(output->model); if (output->model) free(output->model);
for (size_t i = 0; output->modes && i < output->modes->length; ++i) { for (size_t i = 0; output->modes && i < output->modes->length; ++i) {
free(output->modes->items[i]); free(output->modes->items[i]);
} }
list_free(output->modes); list_free(output->modes);
output->impl->destroy(output->state);
free(output); free(output);
} }