[cogl/wip/outputs: 70/71] stash
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/outputs: 70/71] stash
- Date: Fri, 27 Sep 2013 13:44:03 +0000 (UTC)
commit 50bf0bede748338c451c727fbef0f42e8857a3d4
Author: Robert Bragg <robert linux intel com>
Date: Fri Aug 16 16:52:53 2013 +0100
stash
cogl/winsys/cogl-winsys-egl-kms.c | 240 ++++++++++++++++++++++++++-----------
1 files changed, 172 insertions(+), 68 deletions(-)
---
diff --git a/cogl/winsys/cogl-winsys-egl-kms.c b/cogl/winsys/cogl-winsys-egl-kms.c
index 3223765..950dc92 100644
--- a/cogl/winsys/cogl-winsys-egl-kms.c
+++ b/cogl/winsys/cogl-winsys-egl-kms.c
@@ -395,9 +395,9 @@ update_outputs (CoglRenderer *renderer)
kms_output_destroy_cb);
}
- for (j = 0; j < resources->count_modes; j++)
+ for (j = 0; j < connector->count_modes; j++)
{
- drmModeModeInfo *info = &resources->modes[j];
+ drmModeModeInfo *info = &connector->modes[j];
CoglMode *mode = _cogl_mode_new (info->name);
mode->width = info->hdisplay;
@@ -1201,6 +1201,14 @@ get_connector_property (int fd,
return NULL;
}
+/* XXX: NB: Don't assume that the output->state is a reliable cache
+ * of the real hardware state such that state changes can be avoided
+ * by looking for NOP changes between ->state and ->pending since we
+ * sometimes have to deal with the display being changed behind our
+ * back.
+ *
+ * TODO: Support incremental updates in certain cases
+ */
static void
_cogl_winsys_commit_outputs (CoglRenderer *renderer,
CoglError **error)
@@ -1208,6 +1216,14 @@ _cogl_winsys_commit_outputs (CoglRenderer *renderer,
CoglRendererEGL *egl_renderer = renderer->winsys;
CoglRendererKMS *kms_renderer = egl_renderer->platform;
GList *l;
+ CoglBool roll_back = FALSE;
+
+
+ /* If we hit an error at any point while committing the new
+ * configuration then we revert back to here with roll_back
+ * set to TRUE and instead re-commit the previous
+ * configuration */
+ROLL_BACK:
/*
* Ideally we never want to mode-switch to un-initialized
@@ -1232,13 +1248,10 @@ _cogl_winsys_commit_outputs (CoglRenderer *renderer,
{
CoglOutput *output = l->data;
CoglOutputKMS *kms_output = output->winsys;
- CoglOutputState *state_old = output->state;
- CoglOutputState *state_new = output->pending;
- GList *old_overlay0_link, *new_overlay0_link;
+ CoglOutputState *state = roll_back ? output->state : output->pending;
+ drmModeConnector *connector;
drmModeProperty *property;
-
- if (state_old == state_new)
- continue;
+ int i;
connector = drmModeGetConnector (kms_renderer->fd,
kms_output->connector_id);
@@ -1248,82 +1261,152 @@ _cogl_winsys_commit_outputs (CoglRenderer *renderer,
continue;
}
- if (b->output->pending->overlays)
- overlay0_new = state_new->output->pending->overlays->data;
+ if (state->overlays)
+ overlay0 = state->overlays->data;
else
- overlay0_new = NULL;
+ overlay0 = NULL;
+
+ /* If the output has no associated overlays then we assume
+ * it's ok to try and put it into DPMS_MODE_OFF */
+ dpms_mode = overlay0_new ? state_new->dpms_mode : DRM_MODE_DPMS_OFF;
- if (!overlay0_new ||
- state_old->dpms_mode != state_new->dpms_mode)
+ property = get_connector_property (kms_renderer->fd,
+ connector,
+ "DPMS");
+ if (property)
{
- /* If the output has no associated overlays then we assume
- * it's ok to try and put it into DPMS_MODE_OFF */
- dpms_mode = overlay0_new ? state_new->dpms_mode : DRM_MODE_DPMS_OFF;
-
- property = get_connector_property (kms_renderer->fd,
- connector,
- "DPMS");
- if (property)
+ int status = drmModeConnectorSetProperty (kms_renderer->fd,
+ connector->connector_id,
+ property->prop_id,
+ dpms_mode);
+ drmModeFreeProperty (property);
+
+ if (status < 0)
{
- drmModeConnectorSetProperty (kms_renderer->fd,
- connector->connector_id,
- property->prop_id, dpms_mode);
- drmModeFreeProperty (property);
+ const char *dpms_mode_names[] = {
+ "ON",
+ "STANDBY",
+ "SUSPEND",
+ "OFF"
+ };
+
+ g_return_if_fail (roll_back == FALSE);
+
+ roll_back = TRUE;
+ roll_back_error =
+ g_strdup_printf ("Failed to set DPMS state for "
+ "connector %d to %s",
+ dpms_mode_names[dpms_mode]);
+ goto ROLL_BACK;
}
}
- drmModeFreeConnector (connector);
-
- if (!state_new->output->pending->overlays)
+ if (!overlay0)
{
-
+ drmModeFreeConnector (connector);
+ continue;
}
- /* We assume there is always at least one overlay associated
- * with each output */
- g_warn_if_fail (state_new->output->pending->overlays &&
- state-new->output->pending->overlays->data);
- overlay0 = state_new->output->pending->overlays->data;
-
- /* We also assume there is always a source associated with
+ /* We currently assume there is always a source associated with
* each overlay */
g_warn_if_fail (overlay0->onscreen_source);
- overlay0_link = b->output->pending->overlays;
- if (!
-#error FIXME
- /* First setup the crtc mode, using the source from the
- * lowest overlay associated with the output. */
-
- /* Now setup planes for all remaining overlays */
- for (m = a->overlays, n = b->overlays;
- ;
- m = m->next, n = n->next)
+ /* XXX: The corner cases to consider...
+ *
+ * Q: What if we _commit before swapping any onscreen sources?
+ * A: Simply report an error that the overlay sources weren't
+ * all "primed" and roll back the configuration
+ *
+ * Q: What if we call _swap_buffers() before we have committed
+ * an output configuration associating the framebuffer with
+ * a hardware overlay?
+ * A: In this case we'll see that kms_output->overlays is NULL.
+ * We can lock the front buffer and set it as the ->next_bo.
+ * If ->next_bo is already set then we can release ->next_bo
+ * and lock the new front buffer. XXX: what about issuing
+ * a _FRAME_SYNC event for the previous frame?
+ *
+ * How this relates to display configuration:
+ * --
+ * During a _commit we always check that a source either has
+ * a valid ->current_bo or ->next_bo (otherwise we report an
+ * error) since we can't set a mode without a framebuffer and
+ * we don't want to be automatically allocating place holder
+ * framebuffers in corner cases or displaying undefined
+ * buffer contents.
+ *
+ * If ->current_bo is set then we assume there is no
+ * rendering outstanding for that buffer and always use that
+ * buffer when calling drmModeSetCrtc. If we need to call
+ * drmModeSetCrtc() and ->current_bo is not set then we
+ * explicitly synchronize with the GPU to make sure all
+ * rendering to ->next_bo is complete before calling
+ * drmModeSetCrtc().
+ *
+ * If ->current_bo and ->next_bo are set when calling
+ * drmModeSetCrtc then we also call drmModePageFlip() to post
+ * ->next_bo.
+ *
+ * After successfully calling drmModeSetCrtc() then we insert
+ * a reference to the overlay in kms_onscreen->overlays.
+ *
+ * Q: What are the semantics for committing a configuration
+ * while there are pending page flips?
+ * A: Looking at the intel drm driver it looks like setting
+ * a mode starts by disabling the crtc, which involves
+ * waiting for pending flips so I think we can assume
+ * page flip events will *always* be delivered by drm.
+ *
+ * Q: When do we remove references from the
+ * kms_onscreen->overlays list?
+ * A: XXX
+ *
+ * Q: What happens in _swap_buffers when the onscreen is
+ * associated with one or more overlays?
+ * A: iterate through each overlay
+ *
+ * Q: How do we deal with roll-back when this is the first
+ * configuration to be committed?
+ * A: XXX
+ *
+ * Q: How do we deal with an error in drmModePageFlip() also
+ * considering that after the error we might commit a
+ * new display configuration which will want to find
+ * a next/current_bo to reference.
+ * A: We can pretend there was no error and that the page
+ * flip completed immediately by calling page_flip_handler()
+ * directly in this case. This will make sure cogl
+ * dispatches a _FRAME_SYNC event for the frame otherwise
+ * applications may freeze. The main problem here is that
+ * we don't have meaningful timestamp data to pass to
+ * page_flip_handler(). XXX: wont this potentially break the
+ * invariable that we should be able to assume ->current_bo
+ * has no outstanding rendering?
+ *
+ * Q: How do we handle an onscreen framebuffer resize?
+ * A: We don't, you just have to create a new framebuffer
+ */
+
+ for (i = 0; i < connector->count_modes; i++)
{
- CoglOverlay *overlay_m, *overlay_n;
-
- if (m && n && _cogl_overlay_equal (m->data, n->data))
- continue;
-
- overlay_m = m->data;
-
- if (!m || overlay_m->onscreen_source != overlay_n->onscreen_source)
+ drmModeInfo *mode_info = &connector->modes[i];
+ if (strcmp (mode_info->name, state->mode->name) == 0)
{
-
- }
-#error FIXME
- }
-
- /* Note: In the future we might support other sources, such as for
- * video */
- CoglOnscreen *onscreen_source;
-
- /* XXX: src_x must be the first member for _cogl_overlay_equal() to
- * work and all remaining members should be comparable via
- * memcpy() */
-
- /* What region of the source should be overlayed? */
+ CoglOnscreen *onscreen = overlay0->onscreen_source;
+ CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+ CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
+
+ /* XXX: Overlay 0 has limitations with the KMS api */
+#warning "FIXME: actually these should result in a CoglError not a warning"
+ g_warn_if_fail (overlay->src_x != 0);
+ g_warn_if_fail (overlay->src_y != 0);
+ g_warn_if_fail (overlay->src_width != mode_info->width);
+ g_warn_if_fail (overlay->src_height != mode_info->height);
+
+ if (kms_onscreen->current_fb_id)
+ fb_id = kms_onscreen->current_fb_id;
+ else if (kms_onscreen->next_fb_id)
int src_x;
int src_y;
int src_width;
@@ -1332,6 +1415,27 @@ _cogl_winsys_commit_outputs (CoglRenderer *renderer,
int dst_x;
int dst_y;
+ int ret = drmModeSetCrtc (kms_renderer->fd,
+ kms_output->encoder->crtc_id,
+ fb_id, 0, 0,
+ &connector->connector_id, 1,
+ &kms_mode_info);
+
+ }
+ }
+
+#error FIXME
+ /* First setup the crtc mode, using the source from the
+ * lowest overlay associated with the output. */
+
+ /* Now setup planes for all remaining overlays */
+ for (m = state->overlays->next, m; m = m->next)
+ {
+ CoglOverlay *overlay = m->data;
+
+ }
+
+ drmModeFreeConnector (connector);
_cogl_output_update_state (output);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]