update to upstreamed version of patch

This commit is contained in:
Ray Strode 2015-03-23 16:34:11 -04:00
parent 4ae3216143
commit 17768f909e
2 changed files with 103 additions and 157 deletions

View File

@ -1,4 +1,4 @@
From 5c22141866e5335dd111b64349f6ff2ee484a6b4 Mon Sep 17 00:00:00 2001
From 68d9ba3b653a2fe0f0992ea2b6df753b3bfc9d61 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 11 Mar 2015 12:09:51 -0400
Subject: [PATCH] kms-winsys: try to hobble along if driver doesn't support
@ -6,21 +6,20 @@ Subject: [PATCH] kms-winsys: try to hobble along if driver doesn't support
Some drivers ( like mgag200 ) don't yet support drmModePageFlip.
This commit tries to emulate the functionality using drmWaitVBlank
and drmModeSetCrtc in those cases.
Failing all else, it just falls back to flipping right away.
This commit forgoes waiting for vblank and flips right away
in those cases. That prevents the hardware from freezing up the screen,
but does mean there will be some visible tearing.
https://bugzilla.gnome.org/show_bug.cgi?id=746042
---
cogl/winsys/cogl-winsys-egl-kms.c | 130 +++++++++++++++++++++++++++++++++-----
1 file changed, 115 insertions(+), 15 deletions(-)
cogl/winsys/cogl-winsys-egl-kms.c | 52 +++++++++++++++++++++++++++++----------
1 file changed, 39 insertions(+), 13 deletions(-)
diff --git a/cogl/winsys/cogl-winsys-egl-kms.c b/cogl/winsys/cogl-winsys-egl-kms.c
index b06c1da..c66eb45 100644
index b06c1da..c5d014a 100644
--- a/cogl/winsys/cogl-winsys-egl-kms.c
+++ b/cogl/winsys/cogl-winsys-egl-kms.c
@@ -45,104 +45,107 @@
@@ -45,60 +45,61 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>
@ -52,7 +51,6 @@ index b06c1da..c66eb45 100644
struct gbm_device *gbm;
CoglClosure *swap_notify_idle;
+ CoglBool page_flips_not_supported;
+ CoglBool vblank_not_supported;
} CoglRendererKMS;
typedef struct _CoglOutputKMS
@ -83,52 +81,7 @@ index b06c1da..c66eb45 100644
int pending;
} CoglFlipKMS;
typedef struct _CoglOnscreenKMS
{
struct gbm_surface *surface;
uint32_t current_fb_id;
uint32_t next_fb_id;
struct gbm_bo *current_bo;
struct gbm_bo *next_bo;
CoglBool pending_swap_notify;
EGLSurface *pending_egl_surface;
struct gbm_surface *pending_surface;
} CoglOnscreenKMS;
static const char device_name[] = "/dev/dri/card0";
+static void setup_crtc_modes (CoglDisplay *display, int fb_id);
static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
{
CoglRendererEGL *egl_renderer = renderer->winsys;
CoglRendererKMS *kms_renderer = egl_renderer->platform;
eglTerminate (egl_renderer->edpy);
if (kms_renderer->opened_fd >= 0)
close (kms_renderer->opened_fd);
g_slice_free (CoglRendererKMS, kms_renderer);
g_slice_free (CoglRendererEGL, egl_renderer);
}
static void
flush_pending_swap_notify_cb (void *data,
void *user_data)
{
CoglFramebuffer *framebuffer = data;
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
if (kms_onscreen->pending_swap_notify)
{
@@ -197,101 +200,168 @@ free_current_bo (CoglOnscreen *onscreen)
@@ -197,98 +198,107 @@ free_current_bo (CoglOnscreen *onscreen)
kms_onscreen->current_bo = NULL;
}
}
@ -205,76 +158,17 @@ index b06c1da..c66eb45 100644
+ process_flip (flip);
+}
+
+static void
+process_vblank (CoglFlipKMS *flip)
+{
+ /* Normally the driver would set the next fb up for
+ * scan out after vblank for us and then call the
+ * page flip handler to clean things up.
+ *
+ * Not all drivers support the newer page flipping interface
+ * that provides this functionality, though, so try to emulate
+ * it
+ */
+ if (flip->pending == 1)
+ {
+ CoglOnscreen *onscreen = flip->onscreen;
+ CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+ CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = framebuffer->context;
+ CoglDisplay *display = context->display;
+
+ setup_crtc_modes (display, kms_onscreen->next_fb_id);
+
+ process_flip (flip);
+ }
+}
+
+static void
+vblank_handler (int fd,
+ unsigned int frame,
+ unsigned int sec,
+ unsigned int usec,
+ void *data)
+{
+ CoglFlipKMS *flip = data;
+
+ process_vblank (flip);
+}
+
+static gboolean
+fake_vblank_timeout_handler (gpointer data)
+{
+ CoglFlipKMS *flip = data;
+
+ /* Normally the next fb would get setup for
+ * scan out after a vblank interval.
+ *
+ * Not all drivers support vblank notification, though,
+ * so this handler just processes things right away.
+ */
+ process_vblank (flip);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
handle_drm_event (CoglRendererKMS *kms_renderer)
{
drmEventContext evctx;
+ if (kms_renderer->page_flips_not_supported &&
+ kms_renderer->vblank_not_supported)
+ if (kms_renderer->page_flips_not_supported)
+ return;
+
memset (&evctx, 0, sizeof evctx);
evctx.version = DRM_EVENT_CONTEXT_VERSION;
- evctx.page_flip_handler = page_flip_handler;
+ if (kms_renderer->page_flips_not_supported)
+ evctx.vblank_handler = vblank_handler;
+ else
+ evctx.page_flip_handler = page_flip_handler;
evctx.page_flip_handler = page_flip_handler;
drmHandleEvent (kms_renderer->fd, &evctx);
}
@ -302,10 +196,11 @@ index b06c1da..c66eb45 100644
egl_renderer = renderer->winsys;
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
egl_renderer->platform = g_slice_new0 (CoglRendererKMS);
kms_renderer = egl_renderer->platform;
@@ -552,75 +622,105 @@ setup_crtc_modes (CoglDisplay *display, int fb_id)
@@ -548,81 +558,90 @@ static void
setup_crtc_modes (CoglDisplay *display, int fb_id)
{
CoglDisplayEGL *egl_display = display->winsys;
CoglDisplayKMS *kms_display = egl_display->platform;
CoglRendererEGL *egl_renderer = display->renderer->winsys;
CoglRendererKMS *kms_renderer = egl_renderer->platform;
GList *l;
@ -332,12 +227,12 @@ index b06c1da..c66eb45 100644
CoglRendererEGL *egl_renderer = display->renderer->winsys;
CoglRendererKMS *kms_renderer = egl_renderer->platform;
GList *l;
+ gboolean needs_flip = FALSE;
for (l = kms_display->crtcs; l; l = l->next)
{
CoglKmsCrtc *crtc = l->data;
- int ret;
+ int ret = -1;
int ret;
if (crtc->count == 0 || crtc->ignore)
continue;
@ -345,8 +240,13 @@ index b06c1da..c66eb45 100644
- ret = drmModePageFlip (kms_renderer->fd,
- crtc->id, fb_id,
- DRM_MODE_PAGE_FLIP_EVENT, flip);
+ needs_flip = TRUE;
- if (ret)
+ if (!kms_renderer->page_flips_not_supported)
+ {
{
- g_warning ("Failed to flip: %m");
- continue;
+ ret = drmModePageFlip (kms_renderer->fd,
+ crtc->id, fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, flip);
@ -354,42 +254,15 @@ index b06c1da..c66eb45 100644
+ {
+ g_warning ("Failed to flip: %m");
+ kms_renderer->page_flips_not_supported = TRUE;
+ }
+ }
- if (ret)
+ if (kms_renderer->page_flips_not_supported)
{
- g_warning ("Failed to flip: %m");
- continue;
+ drmVBlank watch_for_next_vblank_operation = { 0 };
+
+ if (!kms_renderer->vblank_not_supported)
+ {
+ /* fall back to older way of waiting for vblanks directly
+ */
+ watch_for_next_vblank_operation.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
+ watch_for_next_vblank_operation.request.sequence = 1;
+ watch_for_next_vblank_operation.request.signal = (gulong) flip;
+
+ ret = drmWaitVBlank (kms_renderer->fd, &watch_for_next_vblank_operation);
+
+ if (ret)
+ {
+ kms_renderer->vblank_not_supported = TRUE;
+ g_warning ("Failed to fall back to waiting for vblanks directly: %m");
+ }
+ break;
+ }
}
+ if (kms_renderer->page_flips_not_supported &&
+ kms_renderer->vblank_not_supported)
+ {
+ g_idle_add (fake_vblank_timeout_handler, flip);
+ }
+
flip->pending++;
}
+
+ if (kms_renderer->page_flips_not_supported && needs_flip)
+ flip->pending = 1;
}
static void
@ -418,6 +291,76 @@ index b06c1da..c66eb45 100644
{
CoglDisplayEGL *egl_display = display->winsys;
CoglDisplayKMS *kms_display;
--
2.3.1
CoglRendererEGL *egl_renderer = display->renderer->winsys;
CoglRendererKMS *kms_renderer = egl_renderer->platform;
@@ -918,60 +937,67 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
/* If this is the first framebuffer to be presented then we now setup the
* crtc modes, else we flip from the previous buffer */
if (kms_display->pending_set_crtc)
{
setup_crtc_modes (context->display, kms_onscreen->next_fb_id);
kms_display->pending_set_crtc = FALSE;
}
flip = g_slice_new0 (CoglFlipKMS);
flip->onscreen = onscreen;
flip_all_crtcs (context->display, flip, kms_onscreen->next_fb_id);
if (flip->pending == 0)
{
drmModeRmFB (kms_renderer->fd, kms_onscreen->next_fb_id);
gbm_surface_release_buffer (kms_onscreen->surface,
kms_onscreen->next_bo);
kms_onscreen->next_bo = NULL;
kms_onscreen->next_fb_id = 0;
g_slice_free (CoglFlipKMS, flip);
flip = NULL;
queue_swap_notify_for_onscreen (onscreen);
}
else
{
/* Ensure the onscreen remains valid while it has any pending flips... */
cogl_object_ref (flip->onscreen);
+
+ /* Process flip right away if we can't wait for vblank */
+ if (kms_renderer->page_flips_not_supported)
+ {
+ setup_crtc_modes (context->display, kms_onscreen->next_fb_id);
+ process_flip (flip);
+ }
}
}
static CoglBool
_cogl_winsys_egl_context_init (CoglContext *context,
CoglError **error)
{
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_SWAP_BUFFERS_EVENT, TRUE);
/* TODO: remove this deprecated feature */
COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT,
TRUE);
COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT,
TRUE);
return TRUE;
}
static CoglBool
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
CoglError **error)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *context = framebuffer->context;
CoglDisplay *display = context->display;
CoglDisplayEGL *egl_display = display->winsys;
CoglDisplayKMS *kms_display = egl_display->platform;
CoglRenderer *renderer = display->renderer;
--
2.3.3

View File

@ -6,7 +6,7 @@
Name: cogl
Version: 1.20.0
Release: 2%{?dist}
Release: 3%{?dist}
Summary: A library for using 3D graphics hardware to draw pretty pictures
Group: Development/Libraries
@ -154,6 +154,9 @@ chrpath --delete $RPM_BUILD_ROOT%{_libdir}/libcogl-pango.so
%endif
%changelog
* Mon Mar 23 2015 Ray Strode <rstrode@redhat.com> 1.20.0-3
- Update to upstreamed version of mgag200 fix
* Wed Mar 11 2015 Ray Strode <rstrode@redhat.com> 1.20.0-2
- Try to fix wayland on mgag200