mirror of
https://github.com/brl/mutter.git
synced 2025-02-04 07:34:09 +00:00
backends/native: Use a pre-sampled bezier pressure curve
Based on the pressure curve control points sample a bezier curve and then look up the pressure at that point of the curve. We sample 256 points and do linear interpolation in between, this strikes a balance between having to calculate the point for all 8K pressure points a modern pen supports while still giving us reasonable detailed curves. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3158 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3399>
This commit is contained in:
parent
4d6add290e
commit
e7ba16689d
@ -31,6 +31,7 @@ meta_input_device_tool_native_finalize (GObject *object)
|
||||
|
||||
g_hash_table_unref (tool->button_map);
|
||||
libinput_tablet_tool_unref (tool->tool);
|
||||
meta_bezier_free (tool->bezier);
|
||||
|
||||
G_OBJECT_CLASS (meta_input_device_tool_native_parent_class)->finalize (object);
|
||||
}
|
||||
@ -49,6 +50,20 @@ meta_input_device_tool_native_init (MetaInputDeviceToolNative *tool)
|
||||
tool->button_map = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
init_pressurecurve (MetaInputDeviceToolNative *tool)
|
||||
{
|
||||
MetaBezier *bezier = meta_bezier_new (N_PRESSURECURVE_POINTS);
|
||||
|
||||
g_clear_pointer (&tool->bezier, meta_bezier_free);
|
||||
meta_bezier_init (bezier,
|
||||
tool->pressure_curve[0].x,
|
||||
tool->pressure_curve[0].y,
|
||||
tool->pressure_curve[1].x,
|
||||
tool->pressure_curve[1].y);
|
||||
tool->bezier = bezier;
|
||||
}
|
||||
|
||||
static ClutterInputAxisFlags
|
||||
translate_axes (struct libinput_tablet_tool *tool)
|
||||
{
|
||||
@ -86,6 +101,8 @@ meta_input_device_tool_native_new (struct libinput_tablet_tool *tool,
|
||||
|
||||
evdev_tool->tool = libinput_tablet_tool_ref (tool);
|
||||
|
||||
init_pressurecurve (evdev_tool);
|
||||
|
||||
return CLUTTER_INPUT_DEVICE_TOOL (evdev_tool);
|
||||
}
|
||||
|
||||
@ -94,6 +111,7 @@ meta_input_device_tool_native_set_pressure_curve_in_impl (ClutterInputDeviceTool
|
||||
double curve[4])
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
graphene_point_t p1, p2;
|
||||
|
||||
g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
|
||||
g_return_if_fail (curve[0] >= 0 && curve[0] <= 1 &&
|
||||
@ -101,11 +119,19 @@ meta_input_device_tool_native_set_pressure_curve_in_impl (ClutterInputDeviceTool
|
||||
curve[2] >= 0 && curve[2] <= 1 &&
|
||||
curve[3] >= 0 && curve[3] <= 1);
|
||||
|
||||
p1.x = curve[0];
|
||||
p1.y = curve[1];
|
||||
p2.x = curve[2];
|
||||
p2.y = curve[3];
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
evdev_tool->pressure_curve[0].x = curve[0];
|
||||
evdev_tool->pressure_curve[0].y = curve[1];
|
||||
evdev_tool->pressure_curve[1].x = curve[2];
|
||||
evdev_tool->pressure_curve[1].y = curve[3];
|
||||
|
||||
if (!graphene_point_equal (&p1, &evdev_tool->pressure_curve[0]) ||
|
||||
!graphene_point_equal (&p2, &evdev_tool->pressure_curve[1]))
|
||||
{
|
||||
evdev_tool->pressure_curve[0] = p1;
|
||||
evdev_tool->pressure_curve[1] = p2;
|
||||
init_pressurecurve (evdev_tool);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -130,42 +156,21 @@ meta_input_device_tool_native_set_button_code_in_impl (ClutterInputDeviceTool *t
|
||||
}
|
||||
}
|
||||
|
||||
static double
|
||||
calculate_bezier_position (double pos,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2)
|
||||
{
|
||||
double int1_y, int2_y;
|
||||
|
||||
pos = CLAMP (pos, 0, 1);
|
||||
|
||||
/* Intersection between 0,0 and x1,y1 */
|
||||
int1_y = pos * y1;
|
||||
|
||||
/* Intersection between x2,y2 and 1,1 */
|
||||
int2_y = (pos * (1 - y2)) + y2;
|
||||
|
||||
/* Find the new position in the line traced by the previous points */
|
||||
return (pos * (int2_y - int1_y)) + int1_y;
|
||||
}
|
||||
|
||||
double
|
||||
meta_input_device_tool_native_translate_pressure_in_impl (ClutterInputDeviceTool *tool,
|
||||
double pressure)
|
||||
{
|
||||
MetaInputDeviceToolNative *evdev_tool;
|
||||
double factor;
|
||||
|
||||
g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), pressure);
|
||||
|
||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||
|
||||
return calculate_bezier_position (CLAMP (pressure, 0, 1),
|
||||
evdev_tool->pressure_curve[0].x,
|
||||
evdev_tool->pressure_curve[0].y,
|
||||
evdev_tool->pressure_curve[1].x,
|
||||
evdev_tool->pressure_curve[1].y);
|
||||
pressure = CLAMP (pressure, 0.0, 1.0);
|
||||
factor = meta_bezier_lookup (evdev_tool->bezier, pressure);
|
||||
|
||||
return pressure * factor;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <graphene.h>
|
||||
#include <libinput.h>
|
||||
|
||||
#include "backends/native/meta-bezier.h"
|
||||
#include "clutter/clutter.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -55,12 +56,15 @@ G_BEGIN_DECLS
|
||||
typedef struct _MetaInputDeviceToolNative MetaInputDeviceToolNative;
|
||||
typedef struct _MetaInputDeviceToolNativeClass MetaInputDeviceToolNativeClass;
|
||||
|
||||
#define N_PRESSURECURVE_POINTS 256
|
||||
|
||||
struct _MetaInputDeviceToolNative
|
||||
{
|
||||
ClutterInputDeviceTool parent_instance;
|
||||
struct libinput_tablet_tool *tool;
|
||||
GHashTable *button_map;
|
||||
graphene_point_t pressure_curve[2];
|
||||
MetaBezier *bezier;
|
||||
};
|
||||
|
||||
struct _MetaInputDeviceToolNativeClass
|
||||
|
Loading…
x
Reference in New Issue
Block a user