summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2012-12-14 13:37:30 -0200
committerKristian Høgsberg <krh@bitplanet.net>2012-12-14 11:27:58 -0500
commit6c01c9c51f612fa6ef12f2eb23f82fb9a190b02e (patch)
treebf0b8ccd81577e8be7f0a46eb15b548643f36e26
parent475cf154b154ae6aef26845df00b43b09ca231e6 (diff)
compositor-drm: Reduce code duplication on drm_output_switch_mode()
Call drm_output_init_egl() instead of duplicating the gbm surface and gl renderer state initialization code. Note that this makes error handling a bit worse. Before, if we failed to allocate a gbm surface we could still recover. Failing the renderer state creation would lead to inconsisten state. Now we end up in inconsistent state on both cases.
-rw-r--r--src/compositor-drm.c87
1 files changed, 29 insertions, 58 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index d443c63..cc72c74 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -935,13 +935,14 @@ choose_mode (struct drm_output *output, struct weston_mode *target_mode)
}
static int
+drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec);
+
+static int
drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
{
struct drm_output *output;
struct drm_mode *drm_mode;
- int ret;
struct drm_compositor *ec;
- struct gbm_surface *surface;
if (output_base == NULL) {
weston_log("output is NULL.\n");
@@ -960,53 +961,16 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
if (!drm_mode) {
weston_log("%s, invalid resolution:%dx%d\n", __func__, mode->width, mode->height);
return -1;
- } else if (&drm_mode->base == output->base.current) {
- return 0;
- } else if (drm_mode->base.width == output->base.current->width &&
- drm_mode->base.height == output->base.current->height) {
- /* only change refresh value */
- ret = drmModeSetCrtc(ec->drm.fd,
- output->crtc_id,
- output->current->fb_id, 0, 0,
- &output->connector_id, 1, &drm_mode->mode_info);
-
- if (ret) {
- weston_log("failed to set mode (%dx%d) %u Hz\n",
- drm_mode->base.width,
- drm_mode->base.height,
- drm_mode->base.refresh / 1000);
- ret = -1;
- } else {
- output->base.current->flags = 0;
- output->base.current = &drm_mode->base;
- drm_mode->base.flags =
- WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
- ret = 0;
- }
-
- return ret;
}
- drm_mode->base.flags =
- WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
-
- surface = gbm_surface_create(ec->gbm,
- drm_mode->base.width,
- drm_mode->base.height,
- GBM_FORMAT_XRGB8888,
- GBM_BO_USE_SCANOUT |
- GBM_BO_USE_RENDERING);
- if (!surface) {
- weston_log("failed to create gbm surface\n");
- return -1;
- }
+ if (&drm_mode->base == output->base.current)
+ return 0;
- gl_renderer_output_destroy(&output->base);
+ output->base.current->flags = 0;
- if (gl_renderer_output_create(&output->base, surface) < 0) {
- weston_log("failed to create renderer output\n");
- goto err_gbm;
- }
+ output->base.current = &drm_mode->base;
+ output->base.current->flags =
+ WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
/* reset rendering stuff. */
if (output->current) {
@@ -1027,16 +991,15 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
}
output->next = NULL;
+ gl_renderer_output_destroy(&output->base);
gbm_surface_destroy(output->surface);
- output->surface = surface;
- /*update output*/
- output->base.current = &drm_mode->base;
- return 0;
+ if (drm_output_init_egl(output, ec) < 0) {
+ weston_log("failed to init output egl state with new mode");
+ return -1;
+ }
-err_gbm:
- gbm_surface_destroy(surface);
- return -1;
+ return 0;
}
static int
@@ -1276,6 +1239,8 @@ find_crtc_for_connector(struct drm_compositor *ec,
static int
drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
{
+ int i, flags;
+
output->surface = gbm_surface_create(ec->gbm,
output->base.current->width,
output->base.current->height,
@@ -1288,16 +1253,22 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
}
if (gl_renderer_output_create(&output->base, output->surface) < 0) {
+ weston_log("failed to create gl renderer output state\n");
gbm_surface_destroy(output->surface);
return -1;
}
- output->cursor_bo[0] =
- gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
- GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
- output->cursor_bo[1] =
- gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
- GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
+ flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE;
+
+ for (i = 0; i < 2; i++) {
+ if (output->cursor_bo[i])
+ continue;
+
+ output->cursor_bo[i] =
+ gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
+ flags);
+ }
+
if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
weston_log("cursor buffers unavailable, using gl cursors\n");
ec->cursors_are_broken = 1;