Compare commits
39 commits
fd3373f9cf
...
1444e82cd8
Author | SHA1 | Date | |
---|---|---|---|
|
1444e82cd8 | ||
|
a9a221933e | ||
|
168839e317 | ||
|
011b6f7c96 | ||
|
a364e785f9 | ||
|
e3bbee2630 | ||
|
b5dffcdc67 | ||
|
0411de33b5 | ||
|
739ad5590b | ||
|
7f88fd419b | ||
|
c9bb8a16a2 | ||
|
efadfc4a94 | ||
|
96ca767e22 | ||
|
9e07b3be72 | ||
|
99bbd37b02 | ||
|
608f6d1223 | ||
|
3214e92918 | ||
|
bc74aadcc2 | ||
|
1815af679f | ||
|
e53f0e1463 | ||
|
f45d4c0c7f | ||
|
f585134c11 | ||
|
0fab816982 | ||
|
4b622fbda8 | ||
|
3715012588 | ||
|
a8cc1739d3 | ||
|
ba06ba24ac | ||
|
abd2c95864 | ||
|
e8d7640316 | ||
|
3a580e4bce | ||
|
04b2b87959 | ||
|
1c57f38daf | ||
|
ac089a1710 | ||
|
fc1532efc4 | ||
|
34ee35a53a | ||
|
a6737a46c7 | ||
|
7786482bd5 | ||
|
3bb02538b9 | ||
|
99808a3365 |
55 changed files with 794 additions and 297 deletions
24
NEWS
24
NEWS
|
@ -1,3 +1,27 @@
|
|||
46.5
|
||||
====
|
||||
* Fix drag and drop between X11 and wayland clients [Carlos; !3821]
|
||||
* Fix drag and drop from grabbing popups [Carlos; !3937]
|
||||
* Fix EGLDevice support [Daniel; !3939]
|
||||
* Fix frozen cursor on some hybrid machines [Daniel; !3950]
|
||||
* Fix touch window dragging with pointer lock enabled [Carlos; !3889]
|
||||
* Fix propagating tablet device removals to clients [Peter; !3955]
|
||||
* Fix tablet input in maximized windows [Peter; !3956]
|
||||
* Reduce damage on window movement [Christian; !3975]
|
||||
* Fix frozen cursor after suspend [Jonas; !3982]
|
||||
* Fix using modifiers on multi-GPU setups [José; !3998]
|
||||
* Fixed crashes [Marco, Jonas; !3978, !3960]
|
||||
* Misc. bug fixes and cleanups [Daniel, Michel, Sebastian, Bilal, Peter;
|
||||
#3597, !3946, !3903, !3914, !3954, !3912, !3837, !3959]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Michel Dänzer, Bilal Elmoussaoui, José Expósito, Carlos Garnacho,
|
||||
Christian Hergert, Peter Hutterer, Marco Trevisan (Treviño), Daniel van Vugt,
|
||||
Sebastian Wick
|
||||
|
||||
Translators:
|
||||
Daniel Șerbănescu [ro], Vasil Pupkin [be]
|
||||
|
||||
46.4
|
||||
====
|
||||
* Fix nested popovers on wayland [Carlos; !3874]
|
||||
|
|
|
@ -137,6 +137,8 @@ struct _ClutterFrameClock
|
|||
|
||||
int64_t last_dispatch_interval_us;
|
||||
|
||||
int64_t deadline_evasion_us;
|
||||
|
||||
char *output_name;
|
||||
};
|
||||
|
||||
|
@ -389,7 +391,8 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
|
|||
|
||||
frame_clock->shortterm_max_update_duration_us =
|
||||
CLAMP (frame_clock->last_dispatch_lateness_us + dispatch_to_swap_us +
|
||||
MAX (swap_to_rendering_done_us, swap_to_flip_us),
|
||||
MAX (swap_to_rendering_done_us, swap_to_flip_us) +
|
||||
frame_clock->deadline_evasion_us,
|
||||
frame_clock->shortterm_max_update_duration_us,
|
||||
frame_clock->refresh_interval_us);
|
||||
|
||||
|
@ -1253,3 +1256,10 @@ clutter_frame_clock_class_init (ClutterFrameClockClass *klass)
|
|||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_set_deadline_evasion (ClutterFrameClock *frame_clock,
|
||||
int64_t deadline_evasion_us)
|
||||
{
|
||||
frame_clock->deadline_evasion_us = deadline_evasion_us;
|
||||
}
|
||||
|
|
|
@ -106,3 +106,7 @@ void clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock,
|
|||
int64_t flip_time_us);
|
||||
|
||||
GString * clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_set_deadline_evasion (ClutterFrameClock *frame_clock,
|
||||
int64_t deadline_evasion_us);
|
||||
|
|
|
@ -740,6 +740,10 @@ clutter_stage_view_schedule_update (ClutterStageView *view)
|
|||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
|
||||
|
||||
if (view_class->schedule_update)
|
||||
view_class->schedule_update (view);
|
||||
|
||||
clutter_frame_clock_schedule_update (priv->frame_clock);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ struct _ClutterStageViewClass
|
|||
ClutterFrame * (* new_frame) (ClutterStageView *view);
|
||||
|
||||
ClutterPaintFlag (* get_default_paint_flags) (ClutterStageView *view);
|
||||
|
||||
void (* schedule_update) (ClutterStageView *view);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
|
|
|
@ -55,7 +55,6 @@ ensure_bits_initialized (CoglGlFramebufferBack *gl_framebuffer_back)
|
|||
cogl_framebuffer_driver_get_framebuffer (driver);
|
||||
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglFramebufferBits *bits = &gl_framebuffer_back->bits;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!gl_framebuffer_back->dirty_bitmasks)
|
||||
return TRUE;
|
||||
|
|
|
@ -65,7 +65,6 @@ ensure_bits_initialized (CoglGlFramebufferFbo *gl_framebuffer_fbo)
|
|||
cogl_framebuffer_driver_get_framebuffer (driver);
|
||||
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglFramebufferBits *bits = &gl_framebuffer_fbo->bits;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!gl_framebuffer_fbo->dirty_bitmasks)
|
||||
return TRUE;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
project('mutter', 'c',
|
||||
version: '46.4',
|
||||
version: '46.5',
|
||||
meson_version: '>= 0.60.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
|
|
@ -609,6 +609,7 @@ init_gpus (MetaBackendNative *native,
|
|||
{
|
||||
MetaBackend *backend = META_BACKEND (native);
|
||||
MetaUdev *udev = meta_backend_native_get_udev (native);
|
||||
MetaKms *kms = meta_backend_native_get_kms (native);
|
||||
g_autoptr (GError) local_error = NULL;
|
||||
MetaUdevDeviceType device_type = 0;
|
||||
GList *devices;
|
||||
|
@ -669,6 +670,8 @@ init_gpus (MetaBackendNative *native,
|
|||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
|
||||
meta_kms_notify_probed (kms);
|
||||
|
||||
if (!meta_backend_is_headless (backend) &&
|
||||
g_list_length (meta_backend_get_gpus (backend)) == 0)
|
||||
{
|
||||
|
|
|
@ -348,6 +348,15 @@ meta_crtc_kms_is_hw_cursor_supported (MetaCrtcNative *crtc_native)
|
|||
return meta_kms_device_has_cursor_plane_for (kms_device, kms_crtc);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
meta_crtc_kms_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc_native);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
|
||||
return meta_kms_crtc_get_deadline_evasion (kms_crtc);
|
||||
}
|
||||
|
||||
MetaKmsPlane *
|
||||
meta_crtc_kms_get_assigned_cursor_plane (MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
|
@ -479,6 +488,7 @@ meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
|
|||
|
||||
crtc_native_class->is_transform_handled = meta_crtc_kms_is_transform_handled;
|
||||
crtc_native_class->is_hw_cursor_supported = meta_crtc_kms_is_hw_cursor_supported;
|
||||
crtc_native_class->get_deadline_evasion = meta_crtc_kms_get_deadline_evasion;
|
||||
|
||||
signals[GAMMA_LUT_CHANGED] =
|
||||
g_signal_new ("gamma-lut-changed",
|
||||
|
|
|
@ -39,6 +39,14 @@ meta_crtc_native_is_hw_cursor_supported (MetaCrtcNative *crtc_native)
|
|||
return klass->is_hw_cursor_supported (crtc_native);
|
||||
}
|
||||
|
||||
int64_t
|
||||
meta_crtc_native_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
{
|
||||
MetaCrtcNativeClass *klass = META_CRTC_NATIVE_GET_CLASS (crtc_native);
|
||||
|
||||
return klass->get_deadline_evasion (crtc_native);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_native_init (MetaCrtcNative *crtc_native)
|
||||
{
|
||||
|
|
|
@ -31,9 +31,12 @@ struct _MetaCrtcNativeClass
|
|||
gboolean (* is_transform_handled) (MetaCrtcNative *crtc_native,
|
||||
MetaMonitorTransform monitor_transform);
|
||||
gboolean (* is_hw_cursor_supported) (MetaCrtcNative *crtc_native);
|
||||
int64_t (* get_deadline_evasion) (MetaCrtcNative *crtc_native);
|
||||
};
|
||||
|
||||
gboolean meta_crtc_native_is_transform_handled (MetaCrtcNative *crtc_native,
|
||||
MetaMonitorTransform transform);
|
||||
|
||||
gboolean meta_crtc_native_is_hw_cursor_supported (MetaCrtcNative *crtc_native);
|
||||
|
||||
int64_t meta_crtc_native_get_deadline_evasion (MetaCrtcNative *crtc_native);
|
||||
|
|
|
@ -70,6 +70,12 @@ meta_crtc_virtual_is_hw_cursor_supported (MetaCrtcNative *crtc_native)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
meta_crtc_virtual_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_virtual_init (MetaCrtcVirtual *crtc_virtual)
|
||||
{
|
||||
|
@ -89,4 +95,6 @@ meta_crtc_virtual_class_init (MetaCrtcVirtualClass *klass)
|
|||
meta_crtc_virtual_is_transform_handled;
|
||||
crtc_native_class->is_hw_cursor_supported =
|
||||
meta_crtc_virtual_is_hw_cursor_supported;
|
||||
crtc_native_class->get_deadline_evasion =
|
||||
meta_crtc_virtual_get_deadline_evasion;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ struct _MetaFrameNative
|
|||
{
|
||||
ClutterFrame base;
|
||||
|
||||
MetaDrmBuffer *buffer;
|
||||
CoglScanout *scanout;
|
||||
|
||||
MetaKmsUpdate *kms_update;
|
||||
};
|
||||
|
||||
|
@ -35,6 +38,9 @@ meta_frame_native_release (ClutterFrame *frame)
|
|||
{
|
||||
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
|
||||
|
||||
g_clear_object (&frame_native->buffer);
|
||||
g_clear_object (&frame_native->scanout);
|
||||
|
||||
g_return_if_fail (!frame_native->kms_update);
|
||||
}
|
||||
|
||||
|
@ -76,3 +82,29 @@ meta_frame_native_has_kms_update (MetaFrameNative *frame_native)
|
|||
{
|
||||
return !!frame_native->kms_update;
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_native_set_buffer (MetaFrameNative *frame_native,
|
||||
MetaDrmBuffer *buffer)
|
||||
{
|
||||
g_set_object (&frame_native->buffer, buffer);
|
||||
}
|
||||
|
||||
MetaDrmBuffer *
|
||||
meta_frame_native_get_buffer (MetaFrameNative *frame_native)
|
||||
{
|
||||
return frame_native->buffer;
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_native_set_scanout (MetaFrameNative *frame_native,
|
||||
CoglScanout *scanout)
|
||||
{
|
||||
g_set_object (&frame_native->scanout, scanout);
|
||||
}
|
||||
|
||||
CoglScanout *
|
||||
meta_frame_native_get_scanout (MetaFrameNative *frame_native)
|
||||
{
|
||||
return frame_native->scanout;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "backends/native/meta-backend-native-types.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "core/util-private.h"
|
||||
|
@ -36,3 +37,13 @@ MetaKmsUpdate * meta_frame_native_steal_kms_update (MetaFrameNative *frame_nativ
|
|||
|
||||
META_EXPORT_TEST
|
||||
gboolean meta_frame_native_has_kms_update (MetaFrameNative *frame_native);
|
||||
|
||||
void meta_frame_native_set_buffer (MetaFrameNative *frame_native,
|
||||
MetaDrmBuffer *buffer);
|
||||
|
||||
MetaDrmBuffer * meta_frame_native_get_buffer (MetaFrameNative *frame_native);
|
||||
|
||||
void meta_frame_native_set_scanout (MetaFrameNative *frame_native,
|
||||
CoglScanout *scanout);
|
||||
|
||||
CoglScanout * meta_frame_native_get_scanout (MetaFrameNative *frame_native);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
#include "backends/native/meta-kms-update-private.h"
|
||||
#include "backends/native/meta-kms-utils.h"
|
||||
|
||||
#define DEADLINE_EVASION_US 800
|
||||
#define DEADLINE_EVASION_WITH_KMS_TOPIC_US 1000
|
||||
#define DEADLINE_EVASION_CONSTANT_US 200
|
||||
|
||||
#define MINIMUM_REFRESH_RATE 30.f
|
||||
|
||||
|
@ -50,6 +49,10 @@ struct _MetaKmsCrtc
|
|||
MetaKmsCrtcState current_state;
|
||||
|
||||
MetaKmsCrtcPropTable prop_table;
|
||||
|
||||
int64_t shortterm_max_dispatch_duration_us;
|
||||
int64_t deadline_evasion_us;
|
||||
int64_t deadline_evasion_update_time_us;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT)
|
||||
|
@ -543,6 +546,33 @@ get_crtc_type_bitmask (MetaKmsCrtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_update_deadline_evasion (MetaKmsCrtc *crtc,
|
||||
int64_t next_presentation_time_us)
|
||||
{
|
||||
/* Do not update long-term max if there has been no measurement */
|
||||
if (!crtc->shortterm_max_dispatch_duration_us)
|
||||
return;
|
||||
|
||||
if (next_presentation_time_us - crtc->deadline_evasion_update_time_us <
|
||||
G_USEC_PER_SEC)
|
||||
return;
|
||||
|
||||
if (crtc->deadline_evasion_us > crtc->shortterm_max_dispatch_duration_us)
|
||||
{
|
||||
/* Exponential drop-off toward the clamped short-term max */
|
||||
crtc->deadline_evasion_us -=
|
||||
(crtc->deadline_evasion_us - crtc->shortterm_max_dispatch_duration_us) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
crtc->deadline_evasion_us = crtc->shortterm_max_dispatch_duration_us;
|
||||
}
|
||||
|
||||
crtc->shortterm_max_dispatch_duration_us = 0;
|
||||
crtc->deadline_evasion_update_time_us = next_presentation_time_us;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
||||
int64_t *out_next_deadline_us,
|
||||
|
@ -610,10 +640,8 @@ meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
|||
*
|
||||
*/
|
||||
|
||||
if (meta_is_topic_enabled (META_DEBUG_KMS))
|
||||
deadline_evasion_us = DEADLINE_EVASION_WITH_KMS_TOPIC_US;
|
||||
else
|
||||
deadline_evasion_us = DEADLINE_EVASION_US;
|
||||
deadline_evasion_us = meta_kms_crtc_get_deadline_evasion (crtc);
|
||||
maybe_update_deadline_evasion (crtc, next_presentation_us);
|
||||
|
||||
vblank_duration_us = meta_calculate_drm_mode_vblank_duration_us (drm_mode);
|
||||
next_deadline_us = next_presentation_us - (vblank_duration_us +
|
||||
|
@ -625,3 +653,33 @@ meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_crtc_update_shortterm_max_dispatch_duration (MetaKmsCrtc *crtc,
|
||||
int64_t duration_us)
|
||||
{
|
||||
int64_t refresh_interval_us;
|
||||
|
||||
if (duration_us <= crtc->shortterm_max_dispatch_duration_us)
|
||||
return;
|
||||
|
||||
refresh_interval_us =
|
||||
(int64_t) (0.5 + G_USEC_PER_SEC /
|
||||
meta_calculate_drm_mode_refresh_rate (&crtc->current_state.drm_mode));
|
||||
|
||||
crtc->shortterm_max_dispatch_duration_us = MIN (duration_us, refresh_interval_us);
|
||||
}
|
||||
|
||||
int64_t
|
||||
meta_kms_crtc_get_deadline_evasion (MetaKmsCrtc *crtc)
|
||||
{
|
||||
int64_t deadline_evasion_us;
|
||||
|
||||
deadline_evasion_us =
|
||||
MAX (crtc->shortterm_max_dispatch_duration_us, crtc->deadline_evasion_us);
|
||||
|
||||
if (!deadline_evasion_us)
|
||||
return 0;
|
||||
|
||||
return deadline_evasion_us + DEADLINE_EVASION_CONSTANT_US;
|
||||
}
|
||||
|
|
|
@ -65,3 +65,8 @@ int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
|
|||
|
||||
META_EXPORT_TEST
|
||||
gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
|
||||
|
||||
void meta_kms_crtc_update_shortterm_max_dispatch_duration (MetaKmsCrtc *crtc,
|
||||
int64_t duration_us);
|
||||
|
||||
int64_t meta_kms_crtc_get_deadline_evasion (MetaKmsCrtc *crtc);
|
||||
|
|
|
@ -643,7 +643,7 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT)
|
||||
if (plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC)
|
||||
{
|
||||
int signaled_sync_file;
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "backends/native/meta-kms-plane-private.h"
|
||||
#include "backends/native/meta-kms-plane.h"
|
||||
#include "backends/native/meta-kms-private.h"
|
||||
#include "backends/native/meta-kms-utils.h"
|
||||
#include "backends/native/meta-thread-private.h"
|
||||
|
||||
#include "meta-default-modes.h"
|
||||
|
@ -71,9 +72,17 @@ typedef struct _CrtcDeadline
|
|||
GSource *source;
|
||||
gboolean armed;
|
||||
gboolean is_deadline_page_flip;
|
||||
int64_t expected_deadline_time_us;
|
||||
int64_t expected_presentation_time_us;
|
||||
gboolean has_expected_presentation_time;
|
||||
} deadline;
|
||||
|
||||
struct {
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaKmsUpdateFlag flags;
|
||||
MetaKmsCrtc *latch_crtc;
|
||||
GSource *source;
|
||||
} submitted_update;
|
||||
} CrtcFrame;
|
||||
|
||||
typedef enum _MetaDeadlineTimerState
|
||||
|
@ -108,6 +117,8 @@ typedef struct _MetaKmsImplDevicePrivate
|
|||
|
||||
GHashTable *crtc_frames;
|
||||
|
||||
gboolean realtime_inhibited_pending_mode_set;
|
||||
|
||||
MetaDeadlineTimerState deadline_timer_state;
|
||||
|
||||
gboolean sync_file_retrieved;
|
||||
|
@ -1165,6 +1176,7 @@ arm_crtc_frame_deadline_timer (CrtcFrame *crtc_frame,
|
|||
timerfd_settime (crtc_frame->deadline.timer_fd,
|
||||
TFD_TIMER_ABSTIME, &its, NULL);
|
||||
|
||||
crtc_frame->deadline.expected_deadline_time_us = next_deadline_us;
|
||||
crtc_frame->deadline.expected_presentation_time_us = next_presentation_us;
|
||||
crtc_frame->deadline.has_expected_presentation_time = next_presentation_us != 0;
|
||||
crtc_frame->deadline.armed = TRUE;
|
||||
|
@ -1197,7 +1209,7 @@ crtc_page_flip_feedback_flipped (MetaKmsCrtc *crtc,
|
|||
CrtcFrame *crtc_frame = user_data;
|
||||
|
||||
if (crtc_frame->deadline.is_deadline_page_flip &&
|
||||
meta_is_topic_enabled (META_DEBUG_KMS))
|
||||
meta_is_topic_enabled (META_DEBUG_KMS_DEADLINE))
|
||||
{
|
||||
struct timeval page_flip_timeval;
|
||||
int64_t presentation_time_us;
|
||||
|
@ -1210,7 +1222,7 @@ crtc_page_flip_feedback_flipped (MetaKmsCrtc *crtc,
|
|||
|
||||
if (crtc_frame->deadline.has_expected_presentation_time)
|
||||
{
|
||||
meta_topic (META_DEBUG_KMS,
|
||||
meta_topic (META_DEBUG_KMS_DEADLINE,
|
||||
"Deadline page flip presentation time: %" G_GINT64_FORMAT " us, "
|
||||
"expected %" G_GINT64_FORMAT " us "
|
||||
"(diff: %" G_GINT64_FORMAT ")",
|
||||
|
@ -1221,7 +1233,7 @@ crtc_page_flip_feedback_flipped (MetaKmsCrtc *crtc,
|
|||
}
|
||||
else
|
||||
{
|
||||
meta_topic (META_DEBUG_KMS,
|
||||
meta_topic (META_DEBUG_KMS_DEADLINE,
|
||||
"Deadline page flip presentation time: %" G_GINT64_FORMAT " us",
|
||||
presentation_time_us);
|
||||
}
|
||||
|
@ -1390,11 +1402,16 @@ crtc_frame_deadline_dispatch (MetaThreadImpl *thread_impl,
|
|||
GError **error)
|
||||
{
|
||||
CrtcFrame *crtc_frame = user_data;
|
||||
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc_frame->crtc);
|
||||
MetaKmsCrtc *crtc = crtc_frame->crtc;
|
||||
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
g_autoptr (MetaKmsFeedback) feedback = NULL;
|
||||
uint64_t timer_value;
|
||||
ssize_t ret;
|
||||
int64_t dispatch_time_us = 0, update_done_time_us, interval_us;
|
||||
|
||||
if (meta_is_topic_enabled (META_DEBUG_KMS_DEADLINE))
|
||||
dispatch_time_us = g_get_monotonic_time ();
|
||||
|
||||
ret = read (crtc_frame->deadline.timer_fd,
|
||||
&timer_value,
|
||||
|
@ -1416,6 +1433,36 @@ crtc_frame_deadline_dispatch (MetaThreadImpl *thread_impl,
|
|||
crtc_frame->crtc,
|
||||
g_steal_pointer (&crtc_frame->pending_update),
|
||||
META_KMS_UPDATE_FLAG_NONE);
|
||||
|
||||
update_done_time_us = g_get_monotonic_time ();
|
||||
/* Calculate how long after the planned start of deadline dispatch it finished */
|
||||
interval_us = update_done_time_us - crtc_frame->deadline.expected_deadline_time_us;
|
||||
|
||||
if (meta_is_topic_enabled (META_DEBUG_KMS_DEADLINE))
|
||||
{
|
||||
int64_t deadline_evasion_us, lateness_us, duration_us, vblank_delta_us;
|
||||
|
||||
deadline_evasion_us = meta_kms_crtc_get_deadline_evasion (crtc);
|
||||
lateness_us = dispatch_time_us -
|
||||
crtc_frame->deadline.expected_deadline_time_us;
|
||||
duration_us = update_done_time_us - dispatch_time_us;
|
||||
vblank_delta_us = deadline_evasion_us - lateness_us - duration_us;
|
||||
|
||||
meta_topic (META_DEBUG_KMS_DEADLINE,
|
||||
"Deadline evasion %3"G_GINT64_FORMAT "µs, "
|
||||
"dispatch started %3"G_GINT64_FORMAT "µs %s and "
|
||||
"completed %3"G_GINT64_FORMAT "µs after that, "
|
||||
"%3"G_GINT64_FORMAT "µs %s start of vblank.",
|
||||
deadline_evasion_us,
|
||||
ABS (lateness_us),
|
||||
lateness_us >= 0 ? "late" : "early",
|
||||
duration_us,
|
||||
ABS (vblank_delta_us),
|
||||
vblank_delta_us >= 0 ? "before" : "after");
|
||||
}
|
||||
|
||||
meta_kms_crtc_update_shortterm_max_dispatch_duration (crtc, interval_us);
|
||||
|
||||
if (meta_kms_feedback_did_pass (feedback))
|
||||
crtc_frame->deadline.is_deadline_page_flip = TRUE;
|
||||
disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
|
@ -1429,6 +1476,8 @@ crtc_frame_free (CrtcFrame *crtc_frame)
|
|||
g_clear_fd (&crtc_frame->deadline.timer_fd, NULL);
|
||||
g_clear_pointer (&crtc_frame->deadline.source, g_source_destroy);
|
||||
g_clear_pointer (&crtc_frame->pending_update, meta_kms_update_free);
|
||||
g_clear_pointer (&crtc_frame->submitted_update.kms_update, meta_kms_update_free);
|
||||
g_clear_pointer (&crtc_frame->submitted_update.source, g_source_destroy);
|
||||
g_free (crtc_frame);
|
||||
}
|
||||
|
||||
|
@ -1470,18 +1519,22 @@ ensure_crtc_frame (MetaKmsImplDevice *impl_device,
|
|||
MetaKmsImpl *impl = meta_kms_impl_device_get_impl (impl_device);
|
||||
MetaThreadImpl *thread_impl = META_THREAD_IMPL (impl);
|
||||
CrtcFrame *crtc_frame;
|
||||
gboolean want_deadline_timer, have_deadline_timer;
|
||||
|
||||
crtc_frame = get_crtc_frame (impl_device, latch_crtc);
|
||||
if (crtc_frame)
|
||||
return crtc_frame;
|
||||
if (!crtc_frame)
|
||||
{
|
||||
crtc_frame = g_new0 (CrtcFrame, 1);
|
||||
crtc_frame->impl_device = impl_device;
|
||||
crtc_frame->crtc = latch_crtc;
|
||||
crtc_frame->deadline.timer_fd = -1;
|
||||
crtc_frame->await_flush = TRUE;
|
||||
g_hash_table_insert (priv->crtc_frames, latch_crtc, crtc_frame);
|
||||
}
|
||||
|
||||
crtc_frame = g_new0 (CrtcFrame, 1);
|
||||
crtc_frame->impl_device = impl_device;
|
||||
crtc_frame->crtc = latch_crtc;
|
||||
crtc_frame->deadline.timer_fd = -1;
|
||||
crtc_frame->await_flush = TRUE;
|
||||
|
||||
if (is_using_deadline_timer (impl_device))
|
||||
want_deadline_timer = is_using_deadline_timer (impl_device);
|
||||
have_deadline_timer = crtc_frame->deadline.timer_fd >= 0;
|
||||
if (want_deadline_timer && !have_deadline_timer)
|
||||
{
|
||||
int timer_fd;
|
||||
GSource *source;
|
||||
|
@ -1506,8 +1559,11 @@ ensure_crtc_frame (MetaKmsImplDevice *impl_device,
|
|||
|
||||
g_source_unref (source);
|
||||
}
|
||||
|
||||
g_hash_table_insert (priv->crtc_frames, latch_crtc, crtc_frame);
|
||||
else if (!want_deadline_timer && have_deadline_timer)
|
||||
{
|
||||
g_clear_fd (&crtc_frame->deadline.timer_fd, NULL);
|
||||
g_clear_pointer (&crtc_frame->deadline.source, g_source_destroy);
|
||||
}
|
||||
|
||||
return crtc_frame;
|
||||
}
|
||||
|
@ -1530,6 +1586,79 @@ queue_update (MetaKmsImplDevice *impl_device,
|
|||
}
|
||||
}
|
||||
|
||||
static gpointer
|
||||
meta_kms_impl_device_update_ready (MetaThreadImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
CrtcFrame *crtc_frame = user_data;
|
||||
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc_frame->crtc);
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
MetaKmsUpdate *update;
|
||||
MetaKmsCrtc *latch_crtc;
|
||||
MetaKmsFeedback *feedback;
|
||||
|
||||
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
|
||||
|
||||
g_clear_pointer (&crtc_frame->submitted_update.source, g_source_destroy);
|
||||
|
||||
update = g_steal_pointer (&crtc_frame->submitted_update.kms_update);
|
||||
meta_kms_update_realize (update, impl_device);
|
||||
|
||||
latch_crtc = g_steal_pointer (&crtc_frame->submitted_update.latch_crtc);
|
||||
|
||||
if (crtc_frame->pending_page_flip &&
|
||||
!meta_kms_update_get_mode_sets (update))
|
||||
{
|
||||
g_assert (latch_crtc);
|
||||
|
||||
meta_topic (META_DEBUG_KMS,
|
||||
"Queuing update on CRTC %u (%s): pending page flip",
|
||||
meta_kms_crtc_get_id (latch_crtc),
|
||||
priv->path);
|
||||
|
||||
queue_update (impl_device, crtc_frame, update);
|
||||
return GINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
if (crtc_frame->pending_update)
|
||||
{
|
||||
meta_kms_update_merge_from (crtc_frame->pending_update, update);
|
||||
meta_kms_update_free (update);
|
||||
update = g_steal_pointer (&crtc_frame->pending_update);
|
||||
disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
}
|
||||
|
||||
meta_kms_device_handle_flush (priv->device, latch_crtc);
|
||||
|
||||
feedback = do_process (impl_device, latch_crtc, update, crtc_frame->submitted_update.flags);
|
||||
|
||||
if (meta_kms_feedback_did_pass (feedback) &&
|
||||
crtc_frame->deadline.armed)
|
||||
disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
|
||||
meta_kms_feedback_unref (feedback);
|
||||
|
||||
return GINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_fd_readable (int fd)
|
||||
{
|
||||
GPollFD poll_fd;
|
||||
|
||||
poll_fd.fd = fd;
|
||||
poll_fd.events = G_IO_IN;
|
||||
poll_fd.revents = 0;
|
||||
|
||||
if (!g_poll (&poll_fd, 1, 0))
|
||||
return FALSE;
|
||||
|
||||
return (poll_fd.revents & (G_IO_IN | G_IO_NVAL)) != 0;
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_impl_device_handle_update (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update,
|
||||
|
@ -1537,10 +1666,15 @@ meta_kms_impl_device_handle_update (MetaKmsImplDevice *impl_device,
|
|||
{
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
MetaKmsImpl *kms_impl = meta_kms_impl_device_get_impl (impl_device);
|
||||
MetaThreadImpl *thread_impl = META_THREAD_IMPL (kms_impl);
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaKmsCrtc *latch_crtc;
|
||||
CrtcFrame *crtc_frame;
|
||||
MetaKmsFeedback *feedback;
|
||||
g_autoptr (GSource) source = NULL;
|
||||
g_autofree char *name = NULL;
|
||||
int sync_fd = -1;
|
||||
|
||||
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
|
||||
|
||||
|
@ -1561,38 +1695,58 @@ meta_kms_impl_device_handle_update (MetaKmsImplDevice *impl_device,
|
|||
if (!ensure_device_file (impl_device, &error))
|
||||
goto err;
|
||||
|
||||
meta_kms_update_realize (update, impl_device);
|
||||
|
||||
crtc_frame = ensure_crtc_frame (impl_device, latch_crtc);
|
||||
|
||||
crtc_frame->await_flush = FALSE;
|
||||
|
||||
if (crtc_frame->pending_page_flip &&
|
||||
!meta_kms_update_get_mode_sets (update))
|
||||
if (crtc_frame->submitted_update.kms_update)
|
||||
{
|
||||
g_assert (latch_crtc);
|
||||
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_PENDING,
|
||||
"Previously-submitted update wasn't ready yet");
|
||||
goto err;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_KMS,
|
||||
"Queuing update on CRTC %u (%s): pending page flip",
|
||||
meta_kms_crtc_get_id (latch_crtc),
|
||||
priv->path);
|
||||
crtc_frame->await_flush = FALSE;
|
||||
crtc_frame->submitted_update.kms_update = update;
|
||||
crtc_frame->submitted_update.flags = flags;
|
||||
crtc_frame->submitted_update.latch_crtc = latch_crtc;
|
||||
|
||||
queue_update (impl_device, crtc_frame, update);
|
||||
if (is_using_deadline_timer (impl_device))
|
||||
sync_fd = meta_kms_update_get_sync_fd (update);
|
||||
|
||||
if (sync_fd >= 0)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next)
|
||||
{
|
||||
MetaKmsPlaneAssignment *assignment = l->data;
|
||||
|
||||
assignment->flags |= META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC;
|
||||
}
|
||||
}
|
||||
|
||||
if (sync_fd < 0 ||
|
||||
is_fd_readable (sync_fd))
|
||||
{
|
||||
meta_kms_impl_device_update_ready (thread_impl,
|
||||
crtc_frame,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (crtc_frame->pending_update)
|
||||
{
|
||||
meta_kms_update_merge_from (crtc_frame->pending_update, update);
|
||||
meta_kms_update_free (update);
|
||||
update = g_steal_pointer (&crtc_frame->pending_update);
|
||||
disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
}
|
||||
source = meta_thread_impl_register_fd (thread_impl,
|
||||
sync_fd,
|
||||
meta_kms_impl_device_update_ready,
|
||||
crtc_frame);
|
||||
|
||||
meta_kms_device_handle_flush (priv->device, latch_crtc);
|
||||
name = g_strdup_printf ("[mutter] KMS update sync_fd (crtc: %u, %s)",
|
||||
meta_kms_crtc_get_id (latch_crtc),
|
||||
priv->path);
|
||||
g_source_set_name (source, name);
|
||||
g_source_set_priority (source, G_PRIORITY_HIGH + 1);
|
||||
g_source_set_can_recurse (source, FALSE);
|
||||
g_source_set_ready_time (source, -1);
|
||||
|
||||
feedback = do_process (impl_device, latch_crtc, update, flags);
|
||||
meta_kms_feedback_unref (feedback);
|
||||
crtc_frame->submitted_update.source = source;
|
||||
return;
|
||||
|
||||
err:
|
||||
|
@ -1688,6 +1842,25 @@ needs_flush:
|
|||
meta_kms_device_set_needs_flush (meta_kms_crtc_get_device (crtc), crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
disarm_all_deadline_timers (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
GHashTableIter iter;
|
||||
CrtcFrame *crtc_frame;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->crtc_frames);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &crtc_frame))
|
||||
{
|
||||
crtc_frame->deadline.is_deadline_page_flip = FALSE;
|
||||
crtc_frame->await_flush = FALSE;
|
||||
crtc_frame->pending_page_flip = FALSE;
|
||||
g_clear_pointer (&crtc_frame->pending_update, meta_kms_update_free);
|
||||
disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
}
|
||||
}
|
||||
|
||||
static MetaKmsFeedback *
|
||||
process_mode_set_update (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update,
|
||||
|
@ -1701,7 +1874,6 @@ process_mode_set_update (MetaKmsImplDevice *impl_device,
|
|||
MetaKmsFeedback *feedback;
|
||||
CrtcFrame *crtc_frame;
|
||||
GList *l;
|
||||
GHashTableIter iter;
|
||||
|
||||
for (l = meta_kms_update_get_mode_sets (update); l; l = l->next)
|
||||
{
|
||||
|
@ -1720,20 +1892,18 @@ process_mode_set_update (MetaKmsImplDevice *impl_device,
|
|||
update = g_steal_pointer (&crtc_frame->pending_update);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->crtc_frames);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &crtc_frame))
|
||||
{
|
||||
crtc_frame->deadline.is_deadline_page_flip = FALSE;
|
||||
crtc_frame->await_flush = FALSE;
|
||||
crtc_frame->pending_page_flip = FALSE;
|
||||
g_clear_pointer (&crtc_frame->pending_update, meta_kms_update_free);
|
||||
disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
}
|
||||
disarm_all_deadline_timers (impl_device);
|
||||
|
||||
meta_thread_inhibit_realtime_in_impl (thread);
|
||||
feedback = do_process (impl_device, NULL, update, flags);
|
||||
meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
|
||||
if (priv->realtime_inhibited_pending_mode_set)
|
||||
{
|
||||
priv->realtime_inhibited_pending_mode_set = FALSE;
|
||||
meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
}
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
|
@ -1786,6 +1956,8 @@ meta_kms_impl_device_disable (MetaKmsImplDevice *impl_device)
|
|||
if (!priv->device_file)
|
||||
return;
|
||||
|
||||
disarm_all_deadline_timers (impl_device);
|
||||
|
||||
meta_kms_impl_device_hold_fd (impl_device);
|
||||
meta_thread_inhibit_realtime_in_impl (thread);
|
||||
klass->disable (impl_device);
|
||||
|
@ -1924,6 +2096,15 @@ meta_kms_impl_device_finalize (GObject *object)
|
|||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
|
||||
if (priv->realtime_inhibited_pending_mode_set)
|
||||
{
|
||||
MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl);
|
||||
MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
|
||||
priv->realtime_inhibited_pending_mode_set = FALSE;
|
||||
meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
}
|
||||
|
||||
meta_kms_impl_remove_impl_device (priv->impl, impl_device);
|
||||
|
||||
g_list_free_full (priv->planes, g_object_unref);
|
||||
|
@ -1973,6 +2154,16 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
|
|||
|
||||
update_connectors (impl_device, drm_resources, 0);
|
||||
|
||||
if (!priv->crtcs)
|
||||
{
|
||||
MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl);
|
||||
MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
|
||||
g_warn_if_fail (priv->realtime_inhibited_pending_mode_set);
|
||||
meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
priv->realtime_inhibited_pending_mode_set = FALSE;
|
||||
}
|
||||
|
||||
drmModeFreeResources (drm_resources);
|
||||
|
||||
return TRUE;
|
||||
|
@ -2050,6 +2241,8 @@ meta_kms_impl_device_initable_init (GInitable *initable,
|
|||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl);
|
||||
MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
int fd;
|
||||
|
||||
if (!ensure_device_file (impl_device, error))
|
||||
|
@ -2075,6 +2268,9 @@ meta_kms_impl_device_initable_init (GInitable *initable,
|
|||
|
||||
priv->sync_file = -1;
|
||||
|
||||
meta_thread_inhibit_realtime_in_impl (thread);
|
||||
priv->realtime_inhibited_pending_mode_set = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -172,12 +172,32 @@ meta_kms_impl_finalize (GObject *object)
|
|||
G_OBJECT_CLASS (meta_kms_impl_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_setup (MetaThreadImpl *thread_impl)
|
||||
{
|
||||
MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
|
||||
meta_thread_inhibit_realtime_in_impl (thread);
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_impl_notify_probed (MetaKmsImpl *impl)
|
||||
{
|
||||
MetaThreadImpl *thread_impl = META_THREAD_IMPL (impl);
|
||||
MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
|
||||
meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_class_init (MetaKmsImplClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
MetaThreadImplClass *thread_impl_class = META_THREAD_IMPL_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_kms_impl_finalize;
|
||||
|
||||
thread_impl_class->setup = meta_kms_impl_setup;
|
||||
}
|
||||
|
||||
MetaKmsUpdateFilter *
|
||||
|
|
|
@ -53,6 +53,8 @@ void meta_kms_impl_notify_modes_set (MetaKmsImpl *impl);
|
|||
|
||||
MetaKmsImpl * meta_kms_impl_new (MetaKms *kms);
|
||||
|
||||
void meta_kms_impl_notify_probed (MetaKmsImpl *impl);
|
||||
|
||||
MetaKmsUpdateFilter * meta_kms_impl_add_update_filter (MetaKmsImpl *impl,
|
||||
MetaKmsUpdateFilterFunc func,
|
||||
gpointer user_data);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "backends/native/meta-kms-update.h"
|
||||
#include "backends/native/meta-kms-update-private.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "backends/meta-display-config-shared.h"
|
||||
#include "backends/native/meta-kms-connector.h"
|
||||
#include "backends/native/meta-kms-crtc.h"
|
||||
|
@ -51,6 +53,8 @@ struct _MetaKmsUpdate
|
|||
gboolean needs_modeset;
|
||||
|
||||
MetaKmsImplDevice *impl_device;
|
||||
|
||||
int sync_fd;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -1136,6 +1140,8 @@ meta_kms_update_merge_from (MetaKmsUpdate *update,
|
|||
merge_custom_page_flip_from (update, other_update);
|
||||
merge_page_flip_listeners_from (update, other_update);
|
||||
merge_result_listeners_from (update, other_update);
|
||||
|
||||
meta_kms_update_set_sync_fd (update, g_steal_fd (&other_update->sync_fd));
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -1152,6 +1158,7 @@ meta_kms_update_new (MetaKmsDevice *device)
|
|||
update = g_new0 (MetaKmsUpdate, 1);
|
||||
update->device = device;
|
||||
update->is_latchable = TRUE;
|
||||
update->sync_fd = -1;
|
||||
|
||||
return update;
|
||||
}
|
||||
|
@ -1175,6 +1182,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
|
|||
g_list_free_full (update->crtc_color_updates,
|
||||
(GDestroyNotify) meta_kms_crtc_color_updates_free);
|
||||
g_clear_pointer (&update->custom_page_flip, meta_kms_custom_page_flip_free);
|
||||
g_clear_fd (&update->sync_fd, NULL);
|
||||
|
||||
g_free (update);
|
||||
}
|
||||
|
@ -1200,6 +1208,23 @@ meta_kms_update_get_latch_crtc (MetaKmsUpdate *update)
|
|||
return update->latch_crtc;
|
||||
}
|
||||
|
||||
int
|
||||
meta_kms_update_get_sync_fd (MetaKmsUpdate *update)
|
||||
{
|
||||
return update->sync_fd;
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_update_set_sync_fd (MetaKmsUpdate *update,
|
||||
int sync_fd)
|
||||
{
|
||||
if (update->sync_fd == sync_fd)
|
||||
return;
|
||||
|
||||
g_clear_fd (&update->sync_fd, NULL);
|
||||
update->sync_fd = sync_fd;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_kms_update_is_empty (MetaKmsUpdate *update)
|
||||
{
|
||||
|
@ -1207,5 +1232,6 @@ meta_kms_update_is_empty (MetaKmsUpdate *update)
|
|||
!update->plane_assignments &&
|
||||
!update->connector_updates &&
|
||||
!update->crtc_updates &&
|
||||
!update->crtc_color_updates);
|
||||
!update->crtc_color_updates &&
|
||||
!update->custom_page_flip);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef enum _MetaKmsAssignPlaneFlag
|
|||
META_KMS_ASSIGN_PLANE_FLAG_NONE = 0,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED = 1 << 0,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT = 1 << 2,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC = 1 << 2,
|
||||
} MetaKmsAssignPlaneFlag;
|
||||
|
||||
struct _MetaKmsPageFlipListenerVtable
|
||||
|
@ -157,6 +157,13 @@ void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
|
|||
MetaKmsCrtc *crtc,
|
||||
const MetaGammaLut *gamma);
|
||||
|
||||
int
|
||||
meta_kms_update_get_sync_fd (MetaKmsUpdate *update);
|
||||
|
||||
void
|
||||
meta_kms_update_set_sync_fd (MetaKmsUpdate *update,
|
||||
int sync_fd);
|
||||
|
||||
void meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
|
||||
const int *rectangles,
|
||||
int n_rectangles);
|
||||
|
|
|
@ -413,6 +413,23 @@ meta_kms_new (MetaBackend *backend,
|
|||
return kms;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
notify_probed_in_impl (MetaThreadImpl *thread_impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
meta_kms_impl_notify_probed (META_KMS_IMPL (thread_impl));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_notify_probed (MetaKms *kms)
|
||||
{
|
||||
meta_thread_post_impl_task (META_THREAD (kms),
|
||||
notify_probed_in_impl,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_finalize (GObject *object)
|
||||
{
|
||||
|
|
|
@ -64,6 +64,8 @@ MetaKms * meta_kms_new (MetaBackend *backend,
|
|||
MetaKmsFlags flags,
|
||||
GError **error);
|
||||
|
||||
void meta_kms_notify_probed (MetaKms *kms);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_kms_inhibit_kernel_thread (MetaKms *kms);
|
||||
|
||||
|
|
|
@ -102,12 +102,11 @@ struct _MetaOnscreenNative
|
|||
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||
|
||||
ClutterFrame *presented_frame;
|
||||
ClutterFrame *next_frame;
|
||||
|
||||
struct {
|
||||
struct gbm_surface *surface;
|
||||
MetaDrmBuffer *current_fb;
|
||||
MetaDrmBuffer *next_fb;
|
||||
CoglScanout *current_scanout;
|
||||
CoglScanout *next_scanout;
|
||||
} gbm;
|
||||
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
|
@ -144,30 +143,17 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native,
|
|||
CoglOnscreen *onscreen,
|
||||
GError **error);
|
||||
|
||||
static void
|
||||
free_current_bo (CoglOnscreen *onscreen)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
||||
g_clear_object (&onscreen_native->gbm.current_fb);
|
||||
g_clear_object (&onscreen_native->gbm.current_scanout);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
||||
if (!onscreen_native->gbm.next_fb)
|
||||
if (!onscreen_native->next_frame)
|
||||
return;
|
||||
|
||||
free_current_bo (onscreen);
|
||||
|
||||
g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
g_set_object (&onscreen_native->gbm.current_scanout,
|
||||
onscreen_native->gbm.next_scanout);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref);
|
||||
onscreen_native->presented_frame =
|
||||
g_steal_pointer (&onscreen_native->next_frame);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -175,8 +161,7 @@ meta_onscreen_native_clear_next_fb (CoglOnscreen *onscreen)
|
|||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -311,7 +296,7 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
|
|||
frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
|
||||
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
|
||||
|
||||
g_warn_if_fail (!onscreen_native->gbm.next_fb);
|
||||
g_warn_if_fail (!onscreen_native->next_frame);
|
||||
|
||||
meta_onscreen_native_notify_frame_complete (onscreen);
|
||||
}
|
||||
|
@ -528,12 +513,15 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
|
||||
ClutterFrame *frame = onscreen_native->next_frame;
|
||||
MetaFrameNative *frame_native;
|
||||
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaDrmBuffer *buffer;
|
||||
CoglScanout *scanout;
|
||||
MetaKmsPlaneAssignment *plane_assignment;
|
||||
graphene_rect_t src_rect;
|
||||
MtkRectangle dst_rect;
|
||||
|
@ -541,6 +529,8 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||
COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs,
|
||||
"Meta::OnscreenNative::flip_crtc()");
|
||||
|
||||
g_return_if_fail (frame);
|
||||
|
||||
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
|
||||
|
||||
g_assert (meta_gpu_kms_is_crtc_active (gpu_kms, crtc));
|
||||
|
@ -550,14 +540,14 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
buffer = onscreen_native->gbm.next_fb;
|
||||
frame_native = meta_frame_native_from_frame (frame);
|
||||
buffer = meta_frame_native_get_buffer (frame_native);
|
||||
scanout = meta_frame_native_get_scanout (frame_native);
|
||||
|
||||
if (onscreen_native->gbm.next_scanout)
|
||||
if (scanout)
|
||||
{
|
||||
cogl_scanout_get_src_rect (onscreen_native->gbm.next_scanout,
|
||||
&src_rect);
|
||||
cogl_scanout_get_dst_rect (onscreen_native->gbm.next_scanout,
|
||||
&dst_rect);
|
||||
cogl_scanout_get_src_rect (scanout, &src_rect);
|
||||
cogl_scanout_get_dst_rect (scanout, &dst_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -593,6 +583,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||
meta_kms_update_set_flushing (kms_update, kms_crtc);
|
||||
meta_kms_update_set_custom_page_flip (kms_update,
|
||||
custom_egl_stream_page_flip,
|
||||
onscreen_native);
|
||||
|
@ -848,22 +839,24 @@ import_shared_framebuffer (CoglOnscreen *onscreen,
|
|||
}
|
||||
|
||||
static MetaDrmBuffer *
|
||||
copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
|
||||
MetaRendererNativeGpuData *renderer_gpu_data,
|
||||
gboolean *egl_context_changed,
|
||||
MetaDrmBuffer *primary_gpu_fb)
|
||||
copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
|
||||
MetaRendererNativeGpuData *renderer_gpu_data,
|
||||
MetaDrmBuffer *primary_gpu_fb,
|
||||
GError **error)
|
||||
{
|
||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
|
||||
MetaGles3 *gles3 = meta_renderer_native_get_gles3 (renderer_native);
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
|
||||
MetaRenderDevice *render_device;
|
||||
EGLDisplay egl_display;
|
||||
GError *error = NULL;
|
||||
gboolean use_modifiers;
|
||||
MetaDeviceFile *device_file;
|
||||
MetaDrmBufferFlags flags;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
MetaDrmBufferGbm *buffer_gbm = NULL;
|
||||
struct gbm_bo *bo;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu,
|
||||
|
@ -880,16 +873,12 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
|||
secondary_gpu_state->egl_surface,
|
||||
secondary_gpu_state->egl_surface,
|
||||
renderer_gpu_data->secondary.egl_context,
|
||||
&error))
|
||||
error))
|
||||
{
|
||||
g_warning ("Failed to make current: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
g_prefix_error (error, "Failed to make current: ");
|
||||
goto done;
|
||||
}
|
||||
|
||||
*egl_context_changed = TRUE;
|
||||
|
||||
|
||||
buffer_gbm = META_DRM_BUFFER_GBM (primary_gpu_fb);
|
||||
bo = meta_drm_buffer_gbm_get_bo (buffer_gbm);
|
||||
if (!meta_renderer_native_gles3_blit_shared_bo (egl,
|
||||
|
@ -898,21 +887,19 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
|||
renderer_gpu_data->secondary.egl_context,
|
||||
secondary_gpu_state->egl_surface,
|
||||
bo,
|
||||
&error))
|
||||
error))
|
||||
{
|
||||
g_warning ("Failed to blit shared framebuffer: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
g_prefix_error (error, "Failed to blit shared framebuffer: ");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!meta_egl_swap_buffers (egl,
|
||||
egl_display,
|
||||
secondary_gpu_state->egl_surface,
|
||||
&error))
|
||||
error))
|
||||
{
|
||||
g_warning ("Failed to swap buffers: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
g_prefix_error (error, "Failed to swap buffers: ");
|
||||
goto done;
|
||||
}
|
||||
|
||||
use_modifiers = meta_renderer_native_use_modifiers (renderer_native);
|
||||
|
@ -926,13 +913,11 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
|||
meta_drm_buffer_gbm_new_lock_front (device_file,
|
||||
secondary_gpu_state->gbm.surface,
|
||||
flags,
|
||||
&error);
|
||||
error);
|
||||
if (!buffer_gbm)
|
||||
{
|
||||
g_warning ("meta_drm_buffer_gbm_new_lock_front failed: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
g_prefix_error (error, "meta_drm_buffer_gbm_new_lock_front failed: ");
|
||||
goto done;
|
||||
}
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (buffer_gbm),
|
||||
|
@ -940,7 +925,10 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
|||
g_object_ref (primary_gpu_fb),
|
||||
g_object_unref);
|
||||
|
||||
return META_DRM_BUFFER (buffer_gbm);
|
||||
done:
|
||||
_cogl_winsys_egl_ensure_current (cogl_display);
|
||||
|
||||
return buffer_gbm ? META_DRM_BUFFER (buffer_gbm) : NULL;
|
||||
}
|
||||
|
||||
static MetaDrmBufferDumb *
|
||||
|
@ -1192,56 +1180,54 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
|
|||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
update_secondary_gpu_state_post_swap_buffers (CoglOnscreen *onscreen,
|
||||
gboolean *egl_context_changed,
|
||||
MetaDrmBuffer *primary_gpu_fb,
|
||||
MetaDrmBuffer **secondary_gpu_fb)
|
||||
static MetaDrmBuffer *
|
||||
acquire_front_buffer (CoglOnscreen *onscreen,
|
||||
MetaDrmBuffer *primary_gpu_fb,
|
||||
MetaDrmBuffer *secondary_gpu_fb,
|
||||
GError **error)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||
MetaDrmBuffer *imported_fb;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeGpuStatePostSwapBuffers,
|
||||
"update_secondary_gpu_state_post_swap_buffers()");
|
||||
"acquire_front_buffer()");
|
||||
|
||||
secondary_gpu_state = onscreen_native->secondary_gpu_state;
|
||||
if (secondary_gpu_state)
|
||||
{
|
||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||
g_autoptr (MetaDrmBuffer) next_fb = NULL;
|
||||
if (!secondary_gpu_state)
|
||||
return g_object_ref (primary_gpu_fb);
|
||||
|
||||
renderer_gpu_data =
|
||||
meta_renderer_native_get_gpu_data (renderer_native,
|
||||
secondary_gpu_state->gpu_kms);
|
||||
switch (renderer_gpu_data->secondary.copy_mode)
|
||||
{
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO:
|
||||
next_fb = import_shared_framebuffer (onscreen,
|
||||
renderer_gpu_data =
|
||||
meta_renderer_native_get_gpu_data (renderer_native,
|
||||
secondary_gpu_state->gpu_kms);
|
||||
switch (renderer_gpu_data->secondary.copy_mode)
|
||||
{
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO:
|
||||
imported_fb = import_shared_framebuffer (onscreen,
|
||||
secondary_gpu_state,
|
||||
primary_gpu_fb);
|
||||
if (next_fb)
|
||||
break;
|
||||
/* The fallback was prepared in pre_swap_buffers and is currently
|
||||
* in secondary_gpu_fb.
|
||||
*/
|
||||
renderer_gpu_data->secondary.copy_mode =
|
||||
META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY;
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY:
|
||||
next_fb = g_object_ref (*secondary_gpu_fb);
|
||||
break;
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU:
|
||||
next_fb = copy_shared_framebuffer_gpu (onscreen,
|
||||
secondary_gpu_state,
|
||||
renderer_gpu_data,
|
||||
egl_context_changed,
|
||||
primary_gpu_fb);
|
||||
break;
|
||||
}
|
||||
|
||||
g_set_object (secondary_gpu_fb, next_fb);
|
||||
if (imported_fb)
|
||||
return imported_fb;
|
||||
/* The fallback was prepared in pre_swap_buffers and is currently
|
||||
* in secondary_gpu_fb.
|
||||
*/
|
||||
renderer_gpu_data->secondary.copy_mode =
|
||||
META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY;
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY:
|
||||
return g_object_ref (secondary_gpu_fb);
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU:
|
||||
return copy_shared_framebuffer_gpu (onscreen,
|
||||
secondary_gpu_state,
|
||||
renderer_gpu_data,
|
||||
primary_gpu_fb,
|
||||
error);
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1303,7 +1289,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
|
||||
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
|
||||
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
||||
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
|
||||
|
@ -1321,15 +1306,18 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
MetaKmsUpdate *kms_update;
|
||||
CoglOnscreenClass *parent_class;
|
||||
gboolean create_timestamp_query = TRUE;
|
||||
gboolean egl_context_changed = FALSE;
|
||||
MetaPowerSave power_save_mode;
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaDrmBufferFlags buffer_flags;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
g_autoptr (MetaDrmBuffer) primary_gpu_fb = NULL;
|
||||
g_autoptr (MetaDrmBuffer) secondary_gpu_fb = NULL;
|
||||
g_autoptr (MetaDrmBuffer) buffer = NULL;
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
MetaKmsDevice *kms_device;
|
||||
int sync_fd;
|
||||
|
||||
COGL_TRACE_SCOPED_ANCHOR (MetaRendererNativePostKmsUpdate);
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
|
||||
"Meta::OnscreenNative::swap_buffers_with_damage()");
|
||||
|
@ -1383,46 +1371,28 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
g_warning ("Failed to lock front buffer on %s: %s",
|
||||
meta_device_file_get_path (render_device_file),
|
||||
error->message);
|
||||
|
||||
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
|
||||
meta_onscreen_native_notify_frame_complete (onscreen);
|
||||
return;
|
||||
goto swap_failed;
|
||||
}
|
||||
|
||||
primary_gpu_fb = META_DRM_BUFFER (g_steal_pointer (&buffer_gbm));
|
||||
break;
|
||||
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
buffer = acquire_front_buffer (onscreen,
|
||||
primary_gpu_fb,
|
||||
secondary_gpu_fb,
|
||||
&error);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
g_warning ("Failed to acquire front buffer: %s", error->message);
|
||||
goto swap_failed;
|
||||
}
|
||||
|
||||
update_secondary_gpu_state_post_swap_buffers (onscreen,
|
||||
&egl_context_changed,
|
||||
primary_gpu_fb,
|
||||
&secondary_gpu_fb);
|
||||
meta_frame_native_set_buffer (frame_native, buffer);
|
||||
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
|
||||
if (onscreen_native->secondary_gpu_state)
|
||||
g_set_object (&onscreen_native->gbm.next_fb, secondary_gpu_fb);
|
||||
else
|
||||
g_set_object (&onscreen_native->gbm.next_fb, primary_gpu_fb);
|
||||
|
||||
if (!meta_drm_buffer_ensure_fb_id (onscreen_native->gbm.next_fb, &error))
|
||||
if (!meta_drm_buffer_ensure_fb_id (buffer, &error))
|
||||
{
|
||||
g_warning ("Failed to ensure KMS FB ID on %s: %s",
|
||||
meta_device_file_get_path (render_device_file),
|
||||
error->message);
|
||||
|
||||
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
|
||||
meta_onscreen_native_notify_frame_complete (onscreen);
|
||||
return;
|
||||
goto swap_failed;
|
||||
}
|
||||
break;
|
||||
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
||||
|
@ -1433,14 +1403,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* If we changed EGL context, cogl will have the wrong idea about what is
|
||||
* current, making it fail to set it when it needs to. Avoid that by making
|
||||
* EGL_NO_CONTEXT current now, making cogl eventually set the correct
|
||||
* context.
|
||||
*/
|
||||
if (egl_context_changed)
|
||||
_cogl_winsys_egl_ensure_current (cogl_display);
|
||||
g_warn_if_fail (!onscreen_native->next_frame);
|
||||
onscreen_native->next_frame = clutter_frame_ref (frame);
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
|
||||
kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
|
@ -1474,8 +1438,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
return;
|
||||
}
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativePostKmsUpdate,
|
||||
"Meta::OnscreenNative::swap_buffers_with_damage#post_pending_update()");
|
||||
COGL_TRACE_BEGIN_ANCHORED (MetaRendererNativePostKmsUpdate,
|
||||
"Meta::OnscreenNative::swap_buffers_with_damage#post_pending_update()");
|
||||
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
|
@ -1536,9 +1500,17 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
meta_kms_device_get_path (kms_device));
|
||||
|
||||
kms_update = meta_frame_native_steal_kms_update (frame_native);
|
||||
sync_fd = cogl_context_get_latest_sync_fd (cogl_context);
|
||||
meta_kms_update_set_sync_fd (kms_update, sync_fd);
|
||||
meta_kms_device_post_update (kms_device, kms_update,
|
||||
META_KMS_UPDATE_FLAG_NONE);
|
||||
clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
|
||||
return;
|
||||
|
||||
swap_failed:
|
||||
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
|
||||
meta_onscreen_native_notify_frame_complete (onscreen);
|
||||
clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -1571,7 +1543,7 @@ meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
|
|||
assign_primary_plane (crtc_kms,
|
||||
buffer,
|
||||
test_update,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC,
|
||||
&src_rect,
|
||||
&dst_rect);
|
||||
|
||||
|
@ -1606,11 +1578,15 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
|
|||
G_IO_ERROR_PERMISSION_DENIED))
|
||||
{
|
||||
ClutterStageView *view = CLUTTER_STAGE_VIEW (onscreen_native->view);
|
||||
ClutterFrame *next_frame = onscreen_native->next_frame;
|
||||
MetaFrameNative *next_frame_native =
|
||||
meta_frame_native_from_frame (next_frame);
|
||||
CoglScanout *scanout =
|
||||
meta_frame_native_get_scanout (next_frame_native);
|
||||
|
||||
g_warning ("Direct scanout page flip failed: %s", error->message);
|
||||
|
||||
cogl_scanout_notify_failed (onscreen_native->gbm.next_scanout,
|
||||
onscreen);
|
||||
cogl_scanout_notify_failed (scanout, onscreen);
|
||||
clutter_stage_view_add_redraw_clip (view, NULL);
|
||||
clutter_stage_view_schedule_update_now (view);
|
||||
}
|
||||
|
@ -1675,12 +1651,13 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
|||
render_gpu);
|
||||
|
||||
g_warn_if_fail (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_GBM);
|
||||
g_warn_if_fail (!onscreen_native->gbm.next_fb);
|
||||
g_warn_if_fail (!onscreen_native->gbm.next_scanout);
|
||||
|
||||
g_set_object (&onscreen_native->gbm.next_scanout, scanout);
|
||||
g_set_object (&onscreen_native->gbm.next_fb,
|
||||
META_DRM_BUFFER (cogl_scanout_get_buffer (scanout)));
|
||||
g_warn_if_fail (!onscreen_native->next_frame);
|
||||
onscreen_native->next_frame = clutter_frame_ref (frame);
|
||||
|
||||
meta_frame_native_set_scanout (frame_native, scanout);
|
||||
meta_frame_native_set_buffer (frame_native,
|
||||
META_DRM_BUFFER (cogl_scanout_get_buffer (scanout)));
|
||||
|
||||
frame_info->cpu_time_before_buffer_swap_us = g_get_monotonic_time ();
|
||||
|
||||
|
@ -1701,7 +1678,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
|||
onscreen_native->view,
|
||||
onscreen_native->crtc,
|
||||
kms_update,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
|
@ -1786,11 +1763,15 @@ meta_onscreen_native_before_redraw (CoglOnscreen *onscreen,
|
|||
ClutterFrame *frame)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
|
||||
meta_kms_device_await_flush (meta_kms_crtc_get_device (kms_crtc),
|
||||
kms_crtc);
|
||||
if (meta_get_debug_paint_flags () & META_DEBUG_PAINT_SYNC_CURSOR_PRIMARY)
|
||||
{
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
|
||||
meta_kms_device_await_flush (meta_kms_crtc_get_device (kms_crtc), kms_crtc);
|
||||
}
|
||||
|
||||
maybe_update_frame_sync (onscreen_native, frame);
|
||||
}
|
||||
|
||||
|
@ -2043,8 +2024,8 @@ get_supported_egl_modifiers (CoglOnscreen *onscreen,
|
|||
MetaRenderDevice *render_device;
|
||||
EGLDisplay egl_display;
|
||||
EGLint num_modifiers;
|
||||
GArray *modifiers;
|
||||
GError *error = NULL;
|
||||
g_autofree EGLuint64KHR *modifiers = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
gboolean ret;
|
||||
|
||||
gpu = meta_crtc_get_gpu (META_CRTC (crtc_kms));
|
||||
|
@ -2064,22 +2045,20 @@ get_supported_egl_modifiers (CoglOnscreen *onscreen,
|
|||
if (!ret || num_modifiers == 0)
|
||||
return NULL;
|
||||
|
||||
modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t),
|
||||
num_modifiers);
|
||||
modifiers = g_new (typeof (*modifiers), num_modifiers);
|
||||
ret = meta_egl_query_dma_buf_modifiers (egl, egl_display,
|
||||
format, num_modifiers,
|
||||
(EGLuint64KHR *) modifiers->data, NULL,
|
||||
modifiers, NULL,
|
||||
&num_modifiers, &error);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
g_warning ("Failed to query DMABUF modifiers: %s", error->message);
|
||||
g_error_free (error);
|
||||
g_array_free (modifiers, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return modifiers;
|
||||
return g_array_new_take (g_steal_pointer (&modifiers), num_modifiers, FALSE,
|
||||
sizeof (*modifiers));
|
||||
}
|
||||
|
||||
static GArray *
|
||||
|
@ -2126,7 +2105,6 @@ choose_onscreen_egl_config (CoglOnscreen *onscreen,
|
|||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
|
||||
MetaKmsPlane *kms_plane = meta_crtc_kms_get_assigned_primary_plane (crtc_kms);
|
||||
EGLint attrs[MAX_EGL_CONFIG_ATTRIBS];
|
||||
g_autoptr (GError) local_error = NULL;
|
||||
static const uint32_t alphaless_10bpc_formats[] = {
|
||||
GBM_FORMAT_XRGB2101010,
|
||||
GBM_FORMAT_XBGR2101010,
|
||||
|
@ -2865,15 +2843,15 @@ meta_onscreen_native_dispose (GObject *object)
|
|||
|
||||
meta_onscreen_native_detach (onscreen_native);
|
||||
|
||||
g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref);
|
||||
g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref);
|
||||
|
||||
renderer_gpu_data =
|
||||
meta_renderer_native_get_gpu_data (renderer_native,
|
||||
onscreen_native->render_gpu);
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
free_current_bo (onscreen);
|
||||
break;
|
||||
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
||||
g_assert_not_reached ();
|
||||
|
|
|
@ -2172,7 +2172,6 @@ meta_renderer_native_unset_modes (MetaRendererNative *renderer_native)
|
|||
MetaKmsDevice *kms_device =
|
||||
meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
|
||||
GList *k;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
MetaKmsUpdate *kms_update = NULL;
|
||||
|
||||
for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "backends/native/meta-renderer-view-native.h"
|
||||
|
||||
#include "backends/native/meta-crtc-native.h"
|
||||
#include "backends/native/meta-frame-native.h"
|
||||
|
||||
struct _MetaRendererViewNative
|
||||
|
@ -34,18 +35,58 @@ struct _MetaRendererViewNative
|
|||
G_DEFINE_TYPE (MetaRendererViewNative, meta_renderer_view_native,
|
||||
META_TYPE_RENDERER_VIEW)
|
||||
|
||||
static void
|
||||
update_frame_clock_deadline_evasion (MetaRendererView *renderer_view)
|
||||
{
|
||||
ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (renderer_view);
|
||||
ClutterFrameClock *frame_clock;
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcNative *crtc_native;
|
||||
int64_t deadline_evasion_us;
|
||||
|
||||
frame_clock = clutter_stage_view_get_frame_clock (stage_view);
|
||||
crtc = meta_renderer_view_get_crtc (renderer_view);
|
||||
crtc_native = META_CRTC_NATIVE (crtc);
|
||||
|
||||
deadline_evasion_us = meta_crtc_native_get_deadline_evasion (crtc_native);
|
||||
clutter_frame_clock_set_deadline_evasion (frame_clock,
|
||||
deadline_evasion_us);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_view_native_constructed (GObject *object)
|
||||
{
|
||||
MetaRendererView *renderer_view = META_RENDERER_VIEW (object);
|
||||
|
||||
G_OBJECT_CLASS (meta_renderer_view_native_parent_class)->constructed (object);
|
||||
|
||||
update_frame_clock_deadline_evasion (renderer_view);
|
||||
}
|
||||
|
||||
static ClutterFrame *
|
||||
meta_renderer_view_native_new_frame (ClutterStageView *stage_view)
|
||||
{
|
||||
return (ClutterFrame *) meta_frame_native_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_view_native_schedule_update (ClutterStageView *stage_view)
|
||||
{
|
||||
MetaRendererView *renderer_view = META_RENDERER_VIEW (stage_view);
|
||||
|
||||
update_frame_clock_deadline_evasion (renderer_view);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_view_native_class_init (MetaRendererViewNativeClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterStageViewClass *stage_view_class = CLUTTER_STAGE_VIEW_CLASS (klass);
|
||||
|
||||
object_class->constructed = meta_renderer_view_native_constructed;
|
||||
|
||||
stage_view_class->new_frame = meta_renderer_view_native_new_frame;
|
||||
stage_view_class->schedule_update = meta_renderer_view_native_schedule_update;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -568,6 +568,15 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
meta_thread_impl_setup (MetaThreadImpl *thread_impl)
|
||||
{
|
||||
MetaThreadImplClass *klass = META_THREAD_IMPL_GET_CLASS (thread_impl);
|
||||
|
||||
if (klass->setup)
|
||||
klass->setup (thread_impl);
|
||||
}
|
||||
|
||||
void
|
||||
meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
||||
MetaThreadImplRunFlags flags)
|
||||
|
|
|
@ -38,6 +38,8 @@ G_DECLARE_DERIVABLE_TYPE (MetaThreadImpl, meta_thread_impl,
|
|||
struct _MetaThreadImplClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* setup) (MetaThreadImpl *thread_impl);
|
||||
};
|
||||
|
||||
typedef enum _MetaThreadTaskFeedbackType
|
||||
|
@ -70,6 +72,8 @@ void meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
|
|||
|
||||
void meta_thread_impl_terminate (MetaThreadImpl *thread_impl);
|
||||
|
||||
void meta_thread_impl_setup (MetaThreadImpl *thread_impl);
|
||||
|
||||
void meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
||||
MetaThreadImplRunFlags flags);
|
||||
|
||||
|
|
|
@ -333,22 +333,28 @@ request_normal_scheduling (MetaThread *thread,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
should_use_realtime_scheduling_in_impl (MetaThread *thread)
|
||||
can_use_realtime_scheduling_in_impl (MetaThread *thread)
|
||||
{
|
||||
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||
gboolean should_use_realtime_scheduling = FALSE;
|
||||
|
||||
switch (priv->thread_type)
|
||||
{
|
||||
case META_THREAD_TYPE_USER:
|
||||
break;
|
||||
return FALSE;
|
||||
case META_THREAD_TYPE_KERNEL:
|
||||
if (priv->wants_realtime && priv->kernel.realtime_inhibit_count == 0)
|
||||
should_use_realtime_scheduling = TRUE;
|
||||
break;
|
||||
return priv->wants_realtime;
|
||||
}
|
||||
|
||||
return should_use_realtime_scheduling;
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_use_realtime_scheduling_in_impl (MetaThread *thread)
|
||||
{
|
||||
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||
|
||||
return (can_use_realtime_scheduling_in_impl (thread) &&
|
||||
priv->kernel.realtime_inhibit_count == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -417,11 +423,13 @@ thread_impl_func (gpointer user_data)
|
|||
priv->kernel.realtime_inhibit_count = 0;
|
||||
priv->kernel.is_realtime = FALSE;
|
||||
|
||||
meta_thread_impl_setup (impl);
|
||||
|
||||
sync_realtime_scheduling_in_impl (thread);
|
||||
|
||||
if (priv->kernel.is_realtime)
|
||||
if (can_use_realtime_scheduling_in_impl (thread))
|
||||
{
|
||||
g_message ("Made thread '%s' realtime scheduled", priv->name);
|
||||
g_message ("Thread '%s' will be using real time scheduling", priv->name);
|
||||
run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME;
|
||||
}
|
||||
|
||||
|
@ -765,7 +773,6 @@ meta_thread_reset_thread_type (MetaThread *thread,
|
|||
MetaThreadType thread_type)
|
||||
{
|
||||
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||
g_autoptr (GMainContext) thread_context = NULL;
|
||||
|
||||
if (priv->thread_type == thread_type)
|
||||
return;
|
||||
|
|
|
@ -1838,6 +1838,7 @@ meta_window_drag_begin (MetaWindowDrag *window_drag,
|
|||
stage = meta_backend_get_stage (backend);
|
||||
|
||||
window_drag->handler = clutter_actor_new ();
|
||||
clutter_actor_hide (window_drag->handler);
|
||||
clutter_actor_set_name (window_drag->handler,
|
||||
"Window drag helper");
|
||||
g_signal_connect_swapped (window_drag->handler, "event",
|
||||
|
|
|
@ -69,6 +69,7 @@ static const GDebugKey meta_debug_keys[] = {
|
|||
{ "color", META_DEBUG_COLOR },
|
||||
{ "input-events", META_DEBUG_INPUT_EVENTS },
|
||||
{ "eis", META_DEBUG_EIS },
|
||||
{ "kms-deadline", META_DEBUG_KMS_DEADLINE },
|
||||
};
|
||||
|
||||
static gint verbose_topics = 0;
|
||||
|
@ -326,6 +327,8 @@ meta_topic_to_string (MetaDebugTopic topic)
|
|||
return "INPUT_EVENTS";
|
||||
case META_DEBUG_EIS:
|
||||
return "EIS";
|
||||
case META_DEBUG_KMS_DEADLINE:
|
||||
return "KMS_DEADLINE";
|
||||
}
|
||||
|
||||
return "WM";
|
||||
|
|
|
@ -6851,7 +6851,6 @@ meta_window_get_unit_cgroup (MetaWindow *window)
|
|||
g_autofree char *contents = NULL;
|
||||
g_autofree char *complete_path = NULL;
|
||||
g_autofree char *unit_name = NULL;
|
||||
g_autofree char *unit_path = NULL;
|
||||
char *unit_end;
|
||||
pid_t pid;
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
* @META_DEBUG_COLOR: color management
|
||||
* @META_DEBUG_INPUT_EVENTS: input events
|
||||
* @META_DEBUG_EIS: eis state
|
||||
* @META_DEBUG_KMS_DEADLINE: KMS deadline timers
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
|
@ -83,6 +84,7 @@ typedef enum
|
|||
META_DEBUG_COLOR = 1 << 26,
|
||||
META_DEBUG_INPUT_EVENTS = 1 << 27,
|
||||
META_DEBUG_EIS = 1 << 28,
|
||||
META_DEBUG_KMS_DEADLINE = 1 << 29,
|
||||
} MetaDebugTopic;
|
||||
|
||||
META_EXPORT
|
||||
|
|
|
@ -51,11 +51,14 @@ void meta_fatal (const char *format,
|
|||
* MetaDebugPaintFlag:
|
||||
* @META_DEBUG_PAINT_NONE: default
|
||||
* @META_DEBUG_PAINT_OPAQUE_REGION: paint opaque regions
|
||||
* @META_DEBUG_PAINT_SYNC_CURSOR_PRIMARY: make cursor updates await compositing
|
||||
* frames
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_DEBUG_PAINT_NONE = 0,
|
||||
META_DEBUG_PAINT_OPAQUE_REGION = 1 << 0,
|
||||
META_DEBUG_PAINT_SYNC_CURSOR_PRIMARY = 1 << 1,
|
||||
} MetaDebugPaintFlag;
|
||||
|
||||
META_EXPORT
|
||||
|
|
|
@ -35,7 +35,6 @@ get_colord_mock_proxy (void)
|
|||
{
|
||||
GDBusProxy *proxy;
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_autoptr (GVariant) ret = NULL;
|
||||
|
||||
proxy =
|
||||
g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
|
|
|
@ -126,7 +126,6 @@ get_colord_mock_proxy (void)
|
|||
{
|
||||
GDBusProxy *proxy;
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_autoptr (GVariant) ret = NULL;
|
||||
|
||||
proxy =
|
||||
g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
|
@ -259,7 +258,6 @@ get_gsd_color_mock_proxy (void)
|
|||
{
|
||||
GDBusProxy *proxy;
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_autoptr (GVariant) ret = NULL;
|
||||
|
||||
proxy =
|
||||
g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||
|
|
|
@ -318,7 +318,6 @@ meta_test_input_capture_clear_barriers (void)
|
|||
MetaBackend *backend = meta_context_get_backend (test_context);
|
||||
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
||||
g_autoptr (MetaVirtualMonitor) virtual_monitor1 = NULL;
|
||||
g_autoptr (MetaVirtualMonitor) virtual_monitor2 = NULL;
|
||||
g_autoptr (ClutterVirtualInputDevice) virtual_pointer = NULL;
|
||||
InputCaptureTestClient *test_client;
|
||||
|
||||
|
@ -436,7 +435,6 @@ meta_test_input_capture_events (void)
|
|||
MetaBackend *backend = meta_context_get_backend (test_context);
|
||||
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
||||
g_autoptr (MetaVirtualMonitor) virtual_monitor1 = NULL;
|
||||
g_autoptr (MetaVirtualMonitor) virtual_monitor2 = NULL;
|
||||
g_autoptr (ClutterVirtualInputDevice) virtual_pointer = NULL;
|
||||
g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
|
||||
InputCaptureTestClient *test_client;
|
||||
|
@ -595,7 +593,6 @@ main (int argc,
|
|||
char **argv)
|
||||
{
|
||||
g_autoptr (MetaContext) context = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
g_assert_cmpstr (getenv ("GSETTINGS_BACKEND"), ==, "memory");
|
||||
|
||||
|
|
|
@ -100,7 +100,6 @@ meta_backend_test_add_test_device (MetaBackendTest *backend_test,
|
|||
ClutterInputDeviceType device_type,
|
||||
int n_buttons)
|
||||
{
|
||||
g_autoptr (GList) devices = NULL;
|
||||
MetaBackend *backend = META_BACKEND (backend_test);
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
|
|
|
@ -517,6 +517,12 @@ meta_crtc_test_set_gamma_lut (MetaCrtc *crtc,
|
|||
sizeof (uint16_t) * lut->size);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
meta_crtc_test_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_test_finalize (GObject *object)
|
||||
{
|
||||
|
|
|
@ -1147,7 +1147,6 @@ assert_realtime (MetaThreadImpl *thread_impl,
|
|||
GError **error)
|
||||
{
|
||||
g_autoptr (GVariant) ret = NULL;
|
||||
g_autoptr (GVariant) priority_variant = NULL;
|
||||
uint32_t priority = 0;
|
||||
|
||||
g_assert_true (meta_thread_impl_is_realtime (thread_impl));
|
||||
|
@ -1196,7 +1195,6 @@ assert_no_realtime (MetaThreadImpl *thread_impl,
|
|||
GError **error)
|
||||
{
|
||||
g_autoptr (GVariant) ret = NULL;
|
||||
g_autoptr (GVariant) priority_variant = NULL;
|
||||
uint32_t priority = UINT32_MAX;
|
||||
|
||||
g_assert_false (meta_thread_impl_is_realtime (thread_impl));
|
||||
|
|
|
@ -93,7 +93,6 @@ main (int argc,
|
|||
char **argv)
|
||||
{
|
||||
g_autoptr (MetaContext) context = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
context = meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS,
|
||||
META_CONTEXT_TEST_FLAG_NO_X11);
|
||||
|
|
|
@ -168,7 +168,6 @@ main (int argc,
|
|||
char **argv)
|
||||
{
|
||||
g_autoptr (MetaContext) context = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
context = meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS,
|
||||
META_CONTEXT_TEST_FLAG_NO_X11);
|
||||
|
|
|
@ -275,7 +275,6 @@ main (int argc,
|
|||
char **argv)
|
||||
{
|
||||
g_autoptr (MetaContext) context = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
context = meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS,
|
||||
META_CONTEXT_TEST_FLAG_TEST_CLIENT);
|
||||
|
|
|
@ -320,7 +320,6 @@ main (int argc,
|
|||
char **argv)
|
||||
{
|
||||
g_autoptr (MetaContext) context = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
context = test_context =
|
||||
meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS,
|
||||
|
|
|
@ -175,7 +175,6 @@ primary_device_set_selection (struct wl_client *client,
|
|||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandDataDevicePrimary *data_device = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||
MetaWaylandDataSource *source = NULL;
|
||||
|
||||
if (source_resource)
|
||||
|
@ -343,7 +342,6 @@ void
|
|||
meta_wayland_data_device_primary_set_focus (MetaWaylandDataDevicePrimary *data_device,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||
struct wl_client *focus_client = NULL;
|
||||
struct wl_resource *data_device_resource;
|
||||
|
||||
|
|
|
@ -1048,7 +1048,6 @@ data_device_set_selection (struct wl_client *client,
|
|||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
if (source_resource)
|
||||
|
@ -1250,7 +1249,6 @@ void
|
|||
meta_wayland_data_device_set_focus (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_client *focus_client = NULL;
|
||||
struct wl_resource *data_device_resource;
|
||||
|
||||
|
|
|
@ -48,6 +48,12 @@ struct _MetaWaylandInput
|
|||
ClutterGrab *grab;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INVALIDATE_FOCUS_FLAG_DEFAULT = 0,
|
||||
INVALIDATE_FOCUS_FLAG_CANCEL_TOUCH = 1 << 0,
|
||||
} InvalidateFocusFlag;
|
||||
|
||||
static void meta_wayland_input_sync_focus (MetaWaylandInput *input);
|
||||
|
||||
G_DEFINE_FINAL_TYPE (MetaWaylandInput, meta_wayland_input, G_TYPE_OBJECT)
|
||||
|
@ -137,7 +143,8 @@ meta_wayland_event_handler_invalidate_focus (MetaWaylandEventHandler *handler,
|
|||
}
|
||||
|
||||
static void
|
||||
meta_wayland_input_invalidate_all_focus (MetaWaylandInput *input)
|
||||
meta_wayland_input_invalidate_all_focus (MetaWaylandInput *input,
|
||||
InvalidateFocusFlag flags)
|
||||
{
|
||||
MetaWaylandEventHandler *handler;
|
||||
MetaWaylandSeat *seat = input->seat;
|
||||
|
@ -161,7 +168,8 @@ meta_wayland_input_invalidate_all_focus (MetaWaylandInput *input)
|
|||
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
||||
}
|
||||
|
||||
if (meta_wayland_seat_has_touch (seat))
|
||||
if (meta_wayland_seat_has_touch (seat) &&
|
||||
(flags & INVALIDATE_FOCUS_FLAG_CANCEL_TOUCH) != 0)
|
||||
meta_wayland_touch_cancel (seat->touch);
|
||||
|
||||
g_hash_table_iter_init (&iter, seat->tablet_seat->tablets);
|
||||
|
@ -257,7 +265,8 @@ meta_wayland_input_sync_focus (MetaWaylandInput *input)
|
|||
|
||||
g_assert (!wl_list_empty (&input->event_handler_list));
|
||||
handler = wl_container_of (input->event_handler_list.next, handler, link);
|
||||
meta_wayland_input_invalidate_all_focus (input);
|
||||
meta_wayland_input_invalidate_all_focus (input,
|
||||
INVALIDATE_FOCUS_FLAG_CANCEL_TOUCH);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -310,7 +319,8 @@ meta_wayland_input_attach_event_handler (MetaWaylandInput *input,
|
|||
input);
|
||||
}
|
||||
|
||||
meta_wayland_input_invalidate_all_focus (input);
|
||||
meta_wayland_input_invalidate_all_focus (input,
|
||||
INVALIDATE_FOCUS_FLAG_DEFAULT);
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
@ -337,13 +347,8 @@ meta_wayland_input_detach_event_handler (MetaWaylandInput *input,
|
|||
wl_list_remove (&handler->link);
|
||||
|
||||
if (handler_change && !wl_list_empty (&input->event_handler_list))
|
||||
{
|
||||
MetaWaylandEventHandler *head =
|
||||
wl_container_of (input->event_handler_list.next,
|
||||
head, link);
|
||||
|
||||
meta_wayland_input_invalidate_all_focus (input);
|
||||
}
|
||||
meta_wayland_input_invalidate_all_focus (input,
|
||||
INVALIDATE_FOCUS_FLAG_DEFAULT);
|
||||
|
||||
if (input->grab && !should_be_grabbed (input))
|
||||
{
|
||||
|
|
|
@ -56,8 +56,6 @@ struct _MetaWaylandPopupGrab
|
|||
MetaWaylandSeat *seat;
|
||||
MetaWaylandEventHandler *handler;
|
||||
|
||||
int press_count;
|
||||
|
||||
struct wl_client *grab_client;
|
||||
struct wl_list all_popups;
|
||||
};
|
||||
|
@ -118,12 +116,15 @@ popup_grab_get_focus_surface (MetaWaylandEventHandler *handler,
|
|||
}
|
||||
else
|
||||
{
|
||||
MetaWaylandInput *input = meta_wayland_seat_get_input (popup_grab->seat);
|
||||
|
||||
surface = meta_wayland_event_handler_chain_up_get_focus_surface (handler,
|
||||
device,
|
||||
sequence);
|
||||
|
||||
if (surface && surface->resource &&
|
||||
wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
||||
if (!meta_wayland_input_is_current_handler (input, handler) ||
|
||||
(surface && surface->resource &&
|
||||
wl_resource_get_client (surface->resource) == popup_grab->grab_client))
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
@ -140,18 +141,6 @@ popup_grab_focus (MetaWaylandEventHandler *handler,
|
|||
meta_wayland_event_handler_chain_up_focus (handler, device, sequence, surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
popup_grab_press (MetaWaylandEventHandler *handler,
|
||||
const ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaWaylandPopupGrab *popup_grab = user_data;
|
||||
|
||||
popup_grab->press_count++;
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
popup_grab_release (MetaWaylandEventHandler *handler,
|
||||
const ClutterEvent *event,
|
||||
|
@ -162,9 +151,12 @@ popup_grab_release (MetaWaylandEventHandler *handler,
|
|||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
||||
gboolean close_popup;
|
||||
|
||||
close_popup = popup_grab->press_count == 1;
|
||||
|
||||
popup_grab->press_count = MAX (0, popup_grab->press_count - 1);
|
||||
close_popup = __builtin_popcount (clutter_event_get_state (event) &
|
||||
(CLUTTER_BUTTON1_MASK |
|
||||
CLUTTER_BUTTON2_MASK |
|
||||
CLUTTER_BUTTON3_MASK |
|
||||
CLUTTER_BUTTON4_MASK |
|
||||
CLUTTER_BUTTON5_MASK)) <= 1;
|
||||
|
||||
if (close_popup)
|
||||
{
|
||||
|
@ -188,7 +180,7 @@ static MetaWaylandEventInterface popup_event_interface = {
|
|||
popup_grab_get_focus_surface,
|
||||
popup_grab_focus,
|
||||
NULL, /* motion */
|
||||
popup_grab_press,
|
||||
NULL, /* press */
|
||||
popup_grab_release,
|
||||
};
|
||||
|
||||
|
|
|
@ -215,6 +215,9 @@ default_focus (MetaWaylandEventHandler *handler,
|
|||
MetaWaylandSeat *seat = user_data;
|
||||
ClutterInputCapabilities caps;
|
||||
|
||||
if (sequence)
|
||||
return;
|
||||
|
||||
caps = clutter_input_device_get_capabilities (device);
|
||||
|
||||
if (caps &
|
||||
|
@ -432,12 +435,24 @@ meta_wayland_seat_update (MetaWaylandSeat *seat,
|
|||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_ENTER:
|
||||
case CLUTTER_LEAVE:
|
||||
if (clutter_event_get_event_sequence (event))
|
||||
{
|
||||
if (meta_wayland_seat_has_touch (seat))
|
||||
meta_wayland_touch_update (seat->touch, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (meta_wayland_seat_has_pointer (seat))
|
||||
meta_wayland_pointer_update (seat->pointer, event);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
case CLUTTER_SCROLL:
|
||||
case CLUTTER_ENTER:
|
||||
case CLUTTER_LEAVE:
|
||||
if (meta_wayland_seat_has_pointer (seat))
|
||||
meta_wayland_pointer_update (seat->pointer, event);
|
||||
break;
|
||||
|
|
|
@ -356,7 +356,6 @@ meta_wayland_tablet_seat_lookup_pad (MetaWaylandTabletSeat *tablet_seat,
|
|||
|
||||
static MetaWaylandTabletTool *
|
||||
meta_wayland_tablet_seat_ensure_tool (MetaWaylandTabletSeat *tablet_seat,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *device_tool)
|
||||
{
|
||||
MetaWaylandTabletTool *tool;
|
||||
|
@ -365,7 +364,7 @@ meta_wayland_tablet_seat_ensure_tool (MetaWaylandTabletSeat *tablet_seat,
|
|||
|
||||
if (!tool)
|
||||
{
|
||||
tool = meta_wayland_tablet_tool_new (tablet_seat, device, device_tool);
|
||||
tool = meta_wayland_tablet_tool_new (tablet_seat, device_tool);
|
||||
g_hash_table_insert (tablet_seat->tools, device_tool, tool);
|
||||
}
|
||||
|
||||
|
@ -393,7 +392,7 @@ meta_wayland_tablet_seat_update (MetaWaylandTabletSeat *tablet_seat,
|
|||
device_tool = clutter_event_get_device_tool (event);
|
||||
|
||||
if (device && device_tool)
|
||||
tool = meta_wayland_tablet_seat_ensure_tool (tablet_seat, device, device_tool);
|
||||
tool = meta_wayland_tablet_seat_ensure_tool (tablet_seat, device_tool);
|
||||
|
||||
if (!tool)
|
||||
return;
|
||||
|
@ -448,6 +447,8 @@ meta_wayland_tablet_seat_handle_event (MetaWaylandTabletSeat *tablet_seat,
|
|||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
return meta_wayland_tablet_pad_handle_event (pad, event);
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
default:
|
||||
return CLUTTER_EVENT_STOP;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
struct _MetaWaylandTabletTool
|
||||
{
|
||||
MetaWaylandTabletSeat *seat;
|
||||
ClutterInputDevice *device;
|
||||
ClutterInputDeviceTool *device_tool;
|
||||
struct wl_list resource_list;
|
||||
struct wl_list focus_resource_list;
|
||||
|
@ -424,7 +423,6 @@ tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
|
|||
|
||||
MetaWaylandTabletTool *
|
||||
meta_wayland_tablet_tool_new (MetaWaylandTabletSeat *seat,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *device_tool)
|
||||
{
|
||||
MetaWaylandCompositor *compositor =
|
||||
|
@ -436,7 +434,6 @@ meta_wayland_tablet_tool_new (MetaWaylandTabletSeat *seat,
|
|||
|
||||
tool = g_new0 (MetaWaylandTabletTool, 1);
|
||||
tool->seat = seat;
|
||||
tool->device = device;
|
||||
tool->device_tool = device_tool;
|
||||
wl_list_init (&tool->resource_list);
|
||||
wl_list_init (&tool->focus_resource_list);
|
||||
|
@ -635,7 +632,8 @@ meta_wayland_tablet_tool_set_current_surface (MetaWaylandTabletTool *tool,
|
|||
|
||||
tablet_seat = tool->seat;
|
||||
input = meta_wayland_seat_get_input (tablet_seat->seat);
|
||||
meta_wayland_input_invalidate_focus (input, tool->device, NULL);
|
||||
if (tool->current_tablet)
|
||||
meta_wayland_input_invalidate_focus (input, tool->current_tablet->device, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -920,6 +918,7 @@ meta_wayland_tablet_tool_update (MetaWaylandTabletTool *tool,
|
|||
break;
|
||||
case CLUTTER_PROXIMITY_OUT:
|
||||
tool->current_tablet = NULL;
|
||||
meta_wayland_tablet_tool_set_current_surface (tool, NULL);
|
||||
meta_wayland_tablet_tool_set_cursor_surface (tool, NULL);
|
||||
meta_wayland_tablet_tool_update_cursor_surface (tool);
|
||||
g_clear_object (&tool->cursor_renderer);
|
||||
|
@ -1002,7 +1001,7 @@ meta_wayland_tablet_tool_get_grab_info (MetaWaylandTabletTool *tool,
|
|||
meta_wayland_tablet_tool_can_grab_surface (tool, surface, serial))
|
||||
{
|
||||
if (device_out)
|
||||
*device_out = tool->device;
|
||||
*device_out = tool->current_tablet ? NULL : tool->current_tablet->device;
|
||||
|
||||
if (x)
|
||||
*x = tool->grab_x;
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
MetaWaylandTabletTool * meta_wayland_tablet_tool_new (MetaWaylandTabletSeat *seat,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *device_tool);
|
||||
void meta_wayland_tablet_tool_free (MetaWaylandTabletTool *tool);
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ meta_wayland_touch_update (MetaWaylandTouch *touch,
|
|||
sequence = clutter_event_get_event_sequence (event);
|
||||
event_type = clutter_event_type (event);
|
||||
|
||||
if (event_type == CLUTTER_TOUCH_BEGIN)
|
||||
if (event_type == CLUTTER_ENTER)
|
||||
{
|
||||
MetaWaylandSurface *surface = NULL;
|
||||
MetaBackend *backend;
|
||||
|
@ -256,7 +256,8 @@ meta_wayland_touch_update (MetaWaylandTouch *touch,
|
|||
if (!touch_info)
|
||||
return;
|
||||
|
||||
if (event_type != CLUTTER_TOUCH_BEGIN &&
|
||||
if ((event_type == CLUTTER_TOUCH_UPDATE ||
|
||||
event_type == CLUTTER_TOUCH_END) &&
|
||||
!touch_info->begin_delivered)
|
||||
{
|
||||
g_hash_table_remove (touch->touches, sequence);
|
||||
|
|
Loading…
Reference in a new issue