mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
Let MetaMonitorManagerKms handle page flips
This commit completes the move of monitor logic to the monitor mangager. The renderer now only deals with framebuffers, asking the monitor manager to do the crtc flip tracking. https://bugzilla.gnome.org/show_bug.cgi?id=768976
This commit is contained in:
parent
12ef1a5e4b
commit
8bebb8126c
@ -32,6 +32,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <drm.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
@ -75,11 +76,28 @@ typedef struct {
|
||||
uint32_t rotation_map[ALL_TRANSFORMS];
|
||||
} MetaCRTCKms;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pending;
|
||||
|
||||
MetaKmsFlipCallback callback;
|
||||
void *user_data;
|
||||
} MetaKmsFlipClosure;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSource source;
|
||||
|
||||
gpointer fd_tag;
|
||||
MetaMonitorManagerKms *manager_kms;
|
||||
} MetaKmsSource;
|
||||
|
||||
struct _MetaMonitorManagerKms
|
||||
{
|
||||
MetaMonitorManager parent_instance;
|
||||
|
||||
int fd;
|
||||
MetaKmsSource *source;
|
||||
|
||||
drmModeConnector **connectors;
|
||||
unsigned int n_connectors;
|
||||
@ -87,6 +105,8 @@ struct _MetaMonitorManagerKms
|
||||
GUdevClient *udev;
|
||||
|
||||
GSettings *desktop_settings;
|
||||
|
||||
gboolean page_flips_not_supported;
|
||||
};
|
||||
|
||||
struct _MetaMonitorManagerKmsClass
|
||||
@ -954,8 +974,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
MetaPowerSave mode)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
MetaBackend *backend;
|
||||
MetaRenderer *renderer;
|
||||
uint64_t state;
|
||||
unsigned i;
|
||||
|
||||
@ -995,20 +1013,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
meta_output->name, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
backend = meta_get_backend ();
|
||||
renderer = meta_backend_get_renderer (backend);
|
||||
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
meta_renderer_native_set_ignore_crtc (META_RENDERER_NATIVE (renderer),
|
||||
manager->crtcs[i].crtc_id,
|
||||
mode != META_POWER_SAVE_ON);
|
||||
}
|
||||
|
||||
static void
|
||||
crtc_free (CoglKmsCrtc *crtc)
|
||||
{
|
||||
g_slice_free (CoglKmsCrtc, crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1064,29 +1068,21 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaBackend *backend;
|
||||
MetaRenderer *renderer;
|
||||
unsigned i;
|
||||
GPtrArray *cogl_crtcs;
|
||||
int screen_width, screen_height;
|
||||
gboolean ok;
|
||||
GError *error;
|
||||
|
||||
cogl_crtcs = g_ptr_array_new_full (manager->n_crtcs, (GDestroyNotify)crtc_free);
|
||||
screen_width = 0; screen_height = 0;
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaCRTCInfo *crtc_info = crtcs[i];
|
||||
MetaCRTC *crtc = crtc_info->crtc;
|
||||
MetaCRTCKms *crtc_kms = crtc->driver_private;
|
||||
CoglKmsCrtc *cogl_crtc;
|
||||
|
||||
crtc->is_dirty = TRUE;
|
||||
|
||||
cogl_crtc = g_slice_new0 (CoglKmsCrtc);
|
||||
g_ptr_array_add (cogl_crtcs, cogl_crtc);
|
||||
|
||||
if (crtc_info->mode == NULL)
|
||||
{
|
||||
cogl_crtc->id = crtc->crtc_id;
|
||||
|
||||
crtc->rect.x = 0;
|
||||
crtc->rect.y = 0;
|
||||
crtc->rect.width = 0;
|
||||
@ -1096,24 +1092,15 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
else
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
uint32_t *connectors;
|
||||
unsigned int j, n_connectors;
|
||||
unsigned int j;
|
||||
int width, height;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
|
||||
n_connectors = crtc_info->outputs->len;
|
||||
connectors = g_new (uint32_t, n_connectors);
|
||||
|
||||
cogl_crtc->id = crtc->crtc_id;
|
||||
cogl_crtc->connected = n_connectors > 0;
|
||||
|
||||
for (j = 0; j < n_connectors; j++)
|
||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||
{
|
||||
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
||||
|
||||
connectors[j] = output->winsys_id;
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
}
|
||||
@ -1153,7 +1140,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
{
|
||||
MetaCRTC *crtc = &manager->crtcs[i];
|
||||
CoglKmsCrtc *cogl_crtc;
|
||||
|
||||
crtc->logical_monitor = NULL;
|
||||
|
||||
@ -1163,11 +1149,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
continue;
|
||||
}
|
||||
|
||||
cogl_crtc = g_slice_new0 (CoglKmsCrtc);
|
||||
g_ptr_array_add (cogl_crtcs, cogl_crtc);
|
||||
|
||||
cogl_crtc->id = crtc->crtc_id;
|
||||
|
||||
crtc->rect.x = 0;
|
||||
crtc->rect.y = 0;
|
||||
crtc->rect.width = 0;
|
||||
@ -1181,11 +1162,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
error = NULL;
|
||||
ok = meta_renderer_native_set_layout (META_RENDERER_NATIVE (renderer),
|
||||
screen_width, screen_height,
|
||||
(CoglKmsCrtc**)cogl_crtcs->pdata,
|
||||
cogl_crtcs->len,
|
||||
&error);
|
||||
g_ptr_array_unref (cogl_crtcs);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
meta_warning ("Applying display configuration failed: %s\n", error->message);
|
||||
@ -1279,12 +1256,39 @@ on_uevent (GUdevClient *client,
|
||||
meta_monitor_manager_on_hotplug (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
kms_event_check (GSource *source)
|
||||
{
|
||||
MetaKmsSource *kms_source = (MetaKmsSource *) source;
|
||||
|
||||
return g_source_query_unix_fd (source, kms_source->fd_tag) & G_IO_IN;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
kms_event_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaKmsSource *kms_source = (MetaKmsSource *) source;
|
||||
|
||||
meta_monitor_manager_kms_wait_for_flip (kms_source->manager_kms);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static GSourceFuncs kms_event_funcs = {
|
||||
NULL,
|
||||
kms_event_check,
|
||||
kms_event_dispatch
|
||||
};
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||
GSource *source;
|
||||
|
||||
manager_kms->fd = meta_renderer_native_get_kms_fd (renderer_native);
|
||||
|
||||
@ -1295,6 +1299,14 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||
g_signal_connect (manager_kms->udev, "uevent",
|
||||
G_CALLBACK (on_uevent), manager_kms);
|
||||
|
||||
source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource));
|
||||
manager_kms->source = (MetaKmsSource *) source;
|
||||
manager_kms->source->fd_tag = g_source_add_unix_fd (source,
|
||||
manager_kms->fd,
|
||||
G_IO_IN | G_IO_ERR);
|
||||
manager_kms->source->manager_kms = manager_kms;
|
||||
g_source_attach (source, NULL);
|
||||
|
||||
manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
|
||||
}
|
||||
|
||||
@ -1364,6 +1376,104 @@ meta_monitor_manager_kms_apply_crtc_modes (MetaMonitorManagerKms *manager_kms,
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_kms_flip_all_crtcs (MetaMonitorManagerKms *manager_kms,
|
||||
uint32_t fb_id,
|
||||
MetaKmsFlipCallback flip_callback,
|
||||
void *user_data)
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
|
||||
MetaKmsFlipClosure *flip_closure = NULL;
|
||||
unsigned int i;
|
||||
gboolean fb_in_use = FALSE;
|
||||
|
||||
if (manager->power_save_mode != META_POWER_SAVE_ON)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
{
|
||||
MetaCRTC *crtc = &manager->crtcs[i];
|
||||
uint32_t *connectors;
|
||||
unsigned int n_connectors;
|
||||
int ret;
|
||||
|
||||
get_crtc_connectors (manager, crtc, &connectors, &n_connectors);
|
||||
|
||||
if (n_connectors == 0)
|
||||
continue;
|
||||
|
||||
fb_in_use = TRUE;
|
||||
|
||||
if (manager_kms->page_flips_not_supported)
|
||||
continue;
|
||||
|
||||
if (!flip_closure)
|
||||
{
|
||||
flip_closure = g_new0 (MetaKmsFlipClosure, 1);
|
||||
*flip_closure = (MetaKmsFlipClosure) {
|
||||
.pending = 0,
|
||||
.callback = flip_callback,
|
||||
.user_data = user_data
|
||||
};
|
||||
}
|
||||
|
||||
ret = drmModePageFlip (manager_kms->fd,
|
||||
crtc->crtc_id,
|
||||
fb_id,
|
||||
DRM_MODE_PAGE_FLIP_EVENT,
|
||||
flip_closure);
|
||||
if (ret != 0 && ret != -EACCES)
|
||||
{
|
||||
g_warning ("Failed to flip: %s", strerror (-ret));
|
||||
manager_kms->page_flips_not_supported = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
flip_closure->pending++;
|
||||
}
|
||||
|
||||
if (manager_kms->page_flips_not_supported && fb_in_use)
|
||||
{
|
||||
/* If the driver doesn't support page flipping, just set the mode directly
|
||||
* with the new framebuffer.
|
||||
*/
|
||||
meta_monitor_manager_kms_apply_crtc_modes (manager_kms, fb_id);
|
||||
flip_callback (user_data);
|
||||
g_free (flip_closure);
|
||||
}
|
||||
|
||||
return fb_in_use;
|
||||
}
|
||||
|
||||
static void
|
||||
page_flip_handler (int fd,
|
||||
unsigned int frame,
|
||||
unsigned int sec,
|
||||
unsigned int usec,
|
||||
void *data)
|
||||
{
|
||||
MetaKmsFlipClosure *flip_closure = data;
|
||||
|
||||
flip_closure->pending--;
|
||||
if (flip_closure->pending == 0)
|
||||
flip_closure->callback (flip_closure->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_kms_wait_for_flip (MetaMonitorManagerKms *manager_kms)
|
||||
{
|
||||
drmEventContext evctx;
|
||||
|
||||
if (manager_kms->page_flips_not_supported)
|
||||
return;
|
||||
|
||||
memset (&evctx, 0, sizeof evctx);
|
||||
evctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||
evctx.page_flip_handler = page_flip_handler;
|
||||
drmHandleEvent (manager_kms->fd, &evctx);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_dispose (GObject *object)
|
||||
{
|
||||
@ -1381,6 +1491,7 @@ meta_monitor_manager_kms_finalize (GObject *object)
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
|
||||
|
||||
free_resources (manager_kms);
|
||||
g_source_destroy ((GSource *) manager_kms->source);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -37,7 +37,16 @@ typedef struct _MetaMonitorManagerKms MetaMonitorManagerKms;
|
||||
|
||||
GType meta_monitor_manager_kms_get_type (void);
|
||||
|
||||
typedef void (*MetaKmsFlipCallback) (void *user_data);
|
||||
|
||||
void meta_monitor_manager_kms_apply_crtc_modes (MetaMonitorManagerKms *manager_kms,
|
||||
uint32_t fb_id);
|
||||
|
||||
gboolean meta_monitor_manager_kms_flip_all_crtcs (MetaMonitorManagerKms *manager_kms,
|
||||
uint32_t fb_id,
|
||||
MetaKmsFlipCallback flip_callback,
|
||||
void *user_data);
|
||||
|
||||
void meta_monitor_manager_kms_wait_for_flip (MetaMonitorManagerKms *manager_kms);
|
||||
|
||||
#endif /* META_MONITOR_MANAGER_KMS_H */
|
||||
|
@ -67,9 +67,6 @@ struct _MetaRendererNative
|
||||
int kms_fd;
|
||||
struct gbm_device *gbm;
|
||||
CoglClosure *swap_notify_idle;
|
||||
gboolean page_flips_not_supported;
|
||||
|
||||
GList *crtcs;
|
||||
|
||||
int width, height;
|
||||
gboolean pending_set_crtc;
|
||||
@ -90,12 +87,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaRendererNative,
|
||||
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
||||
static const CoglWinsysVtable *parent_vtable;
|
||||
|
||||
typedef struct _CoglFlipKMS
|
||||
{
|
||||
CoglOnscreen *onscreen;
|
||||
int pending;
|
||||
} CoglFlipKMS;
|
||||
|
||||
typedef struct _CoglOnscreenKMS
|
||||
{
|
||||
struct gbm_surface *surface;
|
||||
@ -211,73 +202,6 @@ queue_swap_notify_for_onscreen (CoglOnscreen *onscreen)
|
||||
kms_onscreen->pending_swap_notify = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
process_flip (CoglFlipKMS *flip)
|
||||
{
|
||||
/* We're only ready to dispatch a swap notification once all outputs
|
||||
* have flipped... */
|
||||
flip->pending--;
|
||||
if (flip->pending == 0)
|
||||
{
|
||||
CoglOnscreen *onscreen = flip->onscreen;
|
||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||
CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
|
||||
|
||||
queue_swap_notify_for_onscreen (onscreen);
|
||||
|
||||
free_current_bo (onscreen);
|
||||
|
||||
kms_onscreen->current_fb_id = kms_onscreen->next_fb_id;
|
||||
kms_onscreen->next_fb_id = 0;
|
||||
|
||||
kms_onscreen->current_bo = kms_onscreen->next_bo;
|
||||
kms_onscreen->next_bo = NULL;
|
||||
|
||||
cogl_object_unref (flip->onscreen);
|
||||
|
||||
g_slice_free (CoglFlipKMS, flip);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
page_flip_handler (int fd,
|
||||
unsigned int frame,
|
||||
unsigned int sec,
|
||||
unsigned int usec,
|
||||
void *data)
|
||||
{
|
||||
CoglFlipKMS *flip = data;
|
||||
|
||||
process_flip (flip);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_drm_event (MetaRendererNative *renderer_native)
|
||||
{
|
||||
drmEventContext evctx;
|
||||
|
||||
if (renderer_native->page_flips_not_supported)
|
||||
return;
|
||||
|
||||
memset (&evctx, 0, sizeof evctx);
|
||||
evctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||
evctx.page_flip_handler = page_flip_handler;
|
||||
drmHandleEvent (renderer_native->kms_fd, &evctx);
|
||||
}
|
||||
|
||||
static void
|
||||
dispatch_kms_events (void *user_data, int revents)
|
||||
{
|
||||
CoglRenderer *renderer = user_data;
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
MetaRendererNative *renderer_native = egl_renderer->platform;
|
||||
|
||||
if (!revents)
|
||||
return;
|
||||
|
||||
handle_drm_event (renderer_native);
|
||||
}
|
||||
|
||||
static CoglBool
|
||||
_cogl_winsys_renderer_connect (CoglRenderer *cogl_renderer,
|
||||
CoglError **error)
|
||||
@ -315,13 +239,6 @@ _cogl_winsys_renderer_connect (CoglRenderer *cogl_renderer,
|
||||
if (!_cogl_winsys_egl_renderer_connect_common (cogl_renderer, error))
|
||||
goto fail;
|
||||
|
||||
_cogl_poll_renderer_add_fd (cogl_renderer,
|
||||
renderer_native->kms_fd,
|
||||
COGL_POLL_FD_EVENT_IN,
|
||||
NULL, /* no prepare callback */
|
||||
dispatch_kms_events,
|
||||
cogl_renderer);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
@ -342,63 +259,6 @@ setup_crtc_modes (CoglDisplay *display, int fb_id)
|
||||
meta_monitor_manager_kms_apply_crtc_modes (monitor_manager_kms, fb_id);
|
||||
}
|
||||
|
||||
static void
|
||||
flip_all_crtcs (CoglDisplay *display, CoglFlipKMS *flip, int fb_id)
|
||||
{
|
||||
CoglDisplayEGL *egl_display = display->winsys;
|
||||
MetaRendererNative *renderer_native = egl_display->platform;
|
||||
GList *l;
|
||||
gboolean needs_flip = FALSE;
|
||||
|
||||
for (l = renderer_native->crtcs; l; l = l->next)
|
||||
{
|
||||
CoglKmsCrtc *crtc = l->data;
|
||||
int ret = 0;
|
||||
|
||||
if (!crtc->connected || crtc->ignore)
|
||||
continue;
|
||||
|
||||
needs_flip = TRUE;
|
||||
|
||||
if (!renderer_native->page_flips_not_supported)
|
||||
{
|
||||
ret = drmModePageFlip (renderer_native->kms_fd,
|
||||
crtc->id, fb_id,
|
||||
DRM_MODE_PAGE_FLIP_EVENT, flip);
|
||||
if (ret != 0 && ret != -EACCES)
|
||||
{
|
||||
g_warning ("Failed to flip: %m");
|
||||
renderer_native->page_flips_not_supported = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
flip->pending++;
|
||||
}
|
||||
|
||||
if (renderer_native->page_flips_not_supported && needs_flip)
|
||||
flip->pending = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
crtc_free (CoglKmsCrtc *crtc)
|
||||
{
|
||||
g_slice_free (CoglKmsCrtc, crtc);
|
||||
}
|
||||
|
||||
static CoglKmsCrtc *
|
||||
crtc_copy (CoglKmsCrtc *from)
|
||||
{
|
||||
CoglKmsCrtc *new;
|
||||
|
||||
new = g_slice_new (CoglKmsCrtc);
|
||||
|
||||
*new = *from;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static CoglBool
|
||||
_cogl_winsys_egl_display_setup (CoglDisplay *display,
|
||||
CoglError **error)
|
||||
@ -490,11 +350,36 @@ _cogl_winsys_egl_cleanup_context (CoglDisplay *display)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
flip_callback (void *user_data)
|
||||
{
|
||||
CoglOnscreen *onscreen = user_data;
|
||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||
CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
|
||||
|
||||
queue_swap_notify_for_onscreen (onscreen);
|
||||
|
||||
free_current_bo (onscreen);
|
||||
|
||||
kms_onscreen->current_fb_id = kms_onscreen->next_fb_id;
|
||||
kms_onscreen->next_fb_id = 0;
|
||||
|
||||
kms_onscreen->current_bo = kms_onscreen->next_bo;
|
||||
kms_onscreen->next_bo = NULL;
|
||||
|
||||
cogl_object_unref (onscreen);
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const int *rectangles,
|
||||
int n_rectangles)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaMonitorManagerKms *monitor_manager_kms =
|
||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||
CoglRenderer *renderer = context->display->renderer;
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
@ -502,11 +387,12 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||
CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
|
||||
uint32_t handle, stride;
|
||||
CoglFlipKMS *flip;
|
||||
gboolean fb_in_use;
|
||||
uint32_t next_fb_id;
|
||||
|
||||
/* If we already have a pending swap then block until it completes */
|
||||
while (kms_onscreen->next_fb_id != 0)
|
||||
handle_drm_event (renderer_native);
|
||||
meta_monitor_manager_kms_wait_for_flip (monitor_manager_kms);
|
||||
|
||||
if (kms_onscreen->pending_egl_surface)
|
||||
{
|
||||
@ -564,34 +450,27 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
renderer_native->pending_set_crtc = FALSE;
|
||||
}
|
||||
|
||||
flip = g_slice_new0 (CoglFlipKMS);
|
||||
flip->onscreen = onscreen;
|
||||
next_fb_id = kms_onscreen->next_fb_id;
|
||||
|
||||
flip_all_crtcs (context->display, flip, kms_onscreen->next_fb_id);
|
||||
/* Reference will either be released in flip_callback, or if the fb
|
||||
* wasn't used, indicated by the return value below.
|
||||
*/
|
||||
cogl_object_ref (onscreen);
|
||||
fb_in_use = meta_monitor_manager_kms_flip_all_crtcs (monitor_manager_kms,
|
||||
next_fb_id,
|
||||
flip_callback, onscreen);
|
||||
|
||||
if (flip->pending == 0)
|
||||
if (!fb_in_use)
|
||||
{
|
||||
drmModeRmFB (renderer_native->kms_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 (renderer_native->page_flips_not_supported)
|
||||
{
|
||||
setup_crtc_modes (context->display, kms_onscreen->next_fb_id);
|
||||
process_flip (flip);
|
||||
}
|
||||
g_object_unref (onscreen);
|
||||
}
|
||||
}
|
||||
|
||||
@ -764,8 +643,6 @@ gboolean
|
||||
meta_renderer_native_set_layout (MetaRendererNative *renderer_native,
|
||||
int width,
|
||||
int height,
|
||||
CoglKmsCrtc **crtcs,
|
||||
int n_crtcs,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
@ -774,8 +651,6 @@ meta_renderer_native_set_layout (MetaRendererNative *renderer_native,
|
||||
CoglDisplayEGL *egl_display = cogl_display->winsys;
|
||||
CoglRenderer *renderer = cogl_display->renderer;
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
GList *crtc_list;
|
||||
int i;
|
||||
|
||||
if ((width != renderer_native->width ||
|
||||
height != renderer_native->height) &&
|
||||
@ -844,39 +719,11 @@ meta_renderer_native_set_layout (MetaRendererNative *renderer_native,
|
||||
renderer_native->width = width;
|
||||
renderer_native->height = height;
|
||||
|
||||
g_list_free_full (renderer_native->crtcs, (GDestroyNotify) crtc_free);
|
||||
|
||||
crtc_list = NULL;
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
crtc_list = g_list_prepend (crtc_list, crtc_copy (crtcs[i]));
|
||||
}
|
||||
crtc_list = g_list_reverse (crtc_list);
|
||||
renderer_native->crtcs = crtc_list;
|
||||
|
||||
renderer_native->pending_set_crtc = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_native_set_ignore_crtc (MetaRendererNative *renderer_native,
|
||||
uint32_t id,
|
||||
gboolean ignore)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = renderer_native->crtcs; l; l = l->next)
|
||||
{
|
||||
CoglKmsCrtc *crtc = l->data;
|
||||
if (crtc->id == id)
|
||||
{
|
||||
crtc->ignore = ignore;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const CoglWinsysVtable *
|
||||
get_native_cogl_winsys_vtable (void)
|
||||
{
|
||||
@ -966,8 +813,6 @@ meta_renderer_native_finalize (GObject *object)
|
||||
{
|
||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object);
|
||||
|
||||
g_list_free_full (renderer_native->crtcs, (GDestroyNotify) crtc_free);
|
||||
|
||||
g_clear_pointer (&renderer_native->dummy_gbm_surface, gbm_surface_destroy);
|
||||
g_clear_pointer (&renderer_native->gbm, gbm_device_destroy);
|
||||
|
||||
|
@ -30,14 +30,6 @@
|
||||
|
||||
#include "backends/meta-renderer.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
|
||||
gboolean connected;
|
||||
|
||||
CoglBool ignore;
|
||||
} CoglKmsCrtc;
|
||||
|
||||
#define META_TYPE_RENDERER_NATIVE (meta_renderer_native_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaRendererNative, meta_renderer_native,
|
||||
META, RENDERER_NATIVE,
|
||||
@ -55,8 +47,6 @@ void meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native
|
||||
gboolean meta_renderer_native_set_layout (MetaRendererNative *renderer_native,
|
||||
int width,
|
||||
int height,
|
||||
CoglKmsCrtc **crtcs,
|
||||
int n_crtcs,
|
||||
GError **error);
|
||||
|
||||
void meta_renderer_native_set_ignore_crtc (MetaRendererNative *renderer_native,
|
||||
|
Loading…
Reference in New Issue
Block a user