update to upstreamed version of patch
This commit is contained in:
parent
4ae3216143
commit
17768f909e
@ -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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Wed, 11 Mar 2015 12:09:51 -0400
|
Date: Wed, 11 Mar 2015 12:09:51 -0400
|
||||||
Subject: [PATCH] kms-winsys: try to hobble along if driver doesn't support
|
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.
|
Some drivers ( like mgag200 ) don't yet support drmModePageFlip.
|
||||||
|
|
||||||
This commit tries to emulate the functionality using drmWaitVBlank
|
This commit forgoes waiting for vblank and flips right away
|
||||||
and drmModeSetCrtc in those cases.
|
in those cases. That prevents the hardware from freezing up the screen,
|
||||||
|
but does mean there will be some visible tearing.
|
||||||
Failing all else, it just falls back to flipping right away.
|
|
||||||
|
|
||||||
https://bugzilla.gnome.org/show_bug.cgi?id=746042
|
https://bugzilla.gnome.org/show_bug.cgi?id=746042
|
||||||
---
|
---
|
||||||
cogl/winsys/cogl-winsys-egl-kms.c | 130 +++++++++++++++++++++++++++++++++-----
|
cogl/winsys/cogl-winsys-egl-kms.c | 52 +++++++++++++++++++++++++++++----------
|
||||||
1 file changed, 115 insertions(+), 15 deletions(-)
|
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
|
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
|
--- a/cogl/winsys/cogl-winsys-egl-kms.c
|
||||||
+++ b/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 <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
#include <gbm.h>
|
#include <gbm.h>
|
||||||
@ -52,7 +51,6 @@ index b06c1da..c66eb45 100644
|
|||||||
struct gbm_device *gbm;
|
struct gbm_device *gbm;
|
||||||
CoglClosure *swap_notify_idle;
|
CoglClosure *swap_notify_idle;
|
||||||
+ CoglBool page_flips_not_supported;
|
+ CoglBool page_flips_not_supported;
|
||||||
+ CoglBool vblank_not_supported;
|
|
||||||
} CoglRendererKMS;
|
} CoglRendererKMS;
|
||||||
|
|
||||||
typedef struct _CoglOutputKMS
|
typedef struct _CoglOutputKMS
|
||||||
@ -83,52 +81,7 @@ index b06c1da..c66eb45 100644
|
|||||||
int pending;
|
int pending;
|
||||||
} CoglFlipKMS;
|
} CoglFlipKMS;
|
||||||
|
|
||||||
typedef struct _CoglOnscreenKMS
|
@@ -197,98 +198,107 @@ free_current_bo (CoglOnscreen *onscreen)
|
||||||
{
|
|
||||||
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)
|
|
||||||
kms_onscreen->current_bo = NULL;
|
kms_onscreen->current_bo = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,76 +158,17 @@ index b06c1da..c66eb45 100644
|
|||||||
+ process_flip (flip);
|
+ 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
|
+static void
|
||||||
handle_drm_event (CoglRendererKMS *kms_renderer)
|
handle_drm_event (CoglRendererKMS *kms_renderer)
|
||||||
{
|
{
|
||||||
drmEventContext evctx;
|
drmEventContext evctx;
|
||||||
|
|
||||||
+ if (kms_renderer->page_flips_not_supported &&
|
+ if (kms_renderer->page_flips_not_supported)
|
||||||
+ kms_renderer->vblank_not_supported)
|
|
||||||
+ return;
|
+ return;
|
||||||
+
|
+
|
||||||
memset (&evctx, 0, sizeof evctx);
|
memset (&evctx, 0, sizeof evctx);
|
||||||
evctx.version = DRM_EVENT_CONTEXT_VERSION;
|
evctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||||
- evctx.page_flip_handler = page_flip_handler;
|
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;
|
|
||||||
drmHandleEvent (kms_renderer->fd, &evctx);
|
drmHandleEvent (kms_renderer->fd, &evctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,10 +196,11 @@ index b06c1da..c66eb45 100644
|
|||||||
egl_renderer = renderer->winsys;
|
egl_renderer = renderer->winsys;
|
||||||
|
|
||||||
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
|
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
|
||||||
egl_renderer->platform = g_slice_new0 (CoglRendererKMS);
|
@@ -548,81 +558,90 @@ static void
|
||||||
kms_renderer = egl_renderer->platform;
|
setup_crtc_modes (CoglDisplay *display, int fb_id)
|
||||||
|
{
|
||||||
@@ -552,75 +622,105 @@ 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;
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||||
GList *l;
|
GList *l;
|
||||||
@ -332,12 +227,12 @@ index b06c1da..c66eb45 100644
|
|||||||
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
+ gboolean needs_flip = FALSE;
|
||||||
|
|
||||||
for (l = kms_display->crtcs; l; l = l->next)
|
for (l = kms_display->crtcs; l; l = l->next)
|
||||||
{
|
{
|
||||||
CoglKmsCrtc *crtc = l->data;
|
CoglKmsCrtc *crtc = l->data;
|
||||||
- int ret;
|
int ret;
|
||||||
+ int ret = -1;
|
|
||||||
|
|
||||||
if (crtc->count == 0 || crtc->ignore)
|
if (crtc->count == 0 || crtc->ignore)
|
||||||
continue;
|
continue;
|
||||||
@ -345,8 +240,13 @@ index b06c1da..c66eb45 100644
|
|||||||
- ret = drmModePageFlip (kms_renderer->fd,
|
- ret = drmModePageFlip (kms_renderer->fd,
|
||||||
- crtc->id, fb_id,
|
- crtc->id, fb_id,
|
||||||
- DRM_MODE_PAGE_FLIP_EVENT, flip);
|
- DRM_MODE_PAGE_FLIP_EVENT, flip);
|
||||||
|
+ needs_flip = TRUE;
|
||||||
|
|
||||||
|
- if (ret)
|
||||||
+ if (!kms_renderer->page_flips_not_supported)
|
+ if (!kms_renderer->page_flips_not_supported)
|
||||||
+ {
|
{
|
||||||
|
- g_warning ("Failed to flip: %m");
|
||||||
|
- continue;
|
||||||
+ ret = drmModePageFlip (kms_renderer->fd,
|
+ ret = drmModePageFlip (kms_renderer->fd,
|
||||||
+ crtc->id, fb_id,
|
+ crtc->id, fb_id,
|
||||||
+ DRM_MODE_PAGE_FLIP_EVENT, flip);
|
+ DRM_MODE_PAGE_FLIP_EVENT, flip);
|
||||||
@ -354,42 +254,15 @@ index b06c1da..c66eb45 100644
|
|||||||
+ {
|
+ {
|
||||||
+ g_warning ("Failed to flip: %m");
|
+ g_warning ("Failed to flip: %m");
|
||||||
+ kms_renderer->page_flips_not_supported = TRUE;
|
+ kms_renderer->page_flips_not_supported = TRUE;
|
||||||
+ }
|
+ break;
|
||||||
+ }
|
|
||||||
|
|
||||||
- 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");
|
|
||||||
+ }
|
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
+ if (kms_renderer->page_flips_not_supported &&
|
|
||||||
+ kms_renderer->vblank_not_supported)
|
|
||||||
+ {
|
|
||||||
+ g_idle_add (fake_vblank_timeout_handler, flip);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
flip->pending++;
|
flip->pending++;
|
||||||
}
|
}
|
||||||
|
+
|
||||||
|
+ if (kms_renderer->page_flips_not_supported && needs_flip)
|
||||||
|
+ flip->pending = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -418,6 +291,76 @@ index b06c1da..c66eb45 100644
|
|||||||
{
|
{
|
||||||
CoglDisplayEGL *egl_display = display->winsys;
|
CoglDisplayEGL *egl_display = display->winsys;
|
||||||
CoglDisplayKMS *kms_display;
|
CoglDisplayKMS *kms_display;
|
||||||
--
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||||
2.3.1
|
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
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Name: cogl
|
Name: cogl
|
||||||
Version: 1.20.0
|
Version: 1.20.0
|
||||||
Release: 2%{?dist}
|
Release: 3%{?dist}
|
||||||
Summary: A library for using 3D graphics hardware to draw pretty pictures
|
Summary: A library for using 3D graphics hardware to draw pretty pictures
|
||||||
|
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
@ -154,6 +154,9 @@ chrpath --delete $RPM_BUILD_ROOT%{_libdir}/libcogl-pango.so
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%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
|
* Wed Mar 11 2015 Ray Strode <rstrode@redhat.com> 1.20.0-2
|
||||||
- Try to fix wayland on mgag200
|
- Try to fix wayland on mgag200
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user