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);
|
g_hash_table_unref (tool->button_map);
|
||||||
libinput_tablet_tool_unref (tool->tool);
|
libinput_tablet_tool_unref (tool->tool);
|
||||||
|
meta_bezier_free (tool->bezier);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_input_device_tool_native_parent_class)->finalize (object);
|
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);
|
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
|
static ClutterInputAxisFlags
|
||||||
translate_axes (struct libinput_tablet_tool *tool)
|
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);
|
evdev_tool->tool = libinput_tablet_tool_ref (tool);
|
||||||
|
|
||||||
|
init_pressurecurve (evdev_tool);
|
||||||
|
|
||||||
return CLUTTER_INPUT_DEVICE_TOOL (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])
|
double curve[4])
|
||||||
{
|
{
|
||||||
MetaInputDeviceToolNative *evdev_tool;
|
MetaInputDeviceToolNative *evdev_tool;
|
||||||
|
graphene_point_t p1, p2;
|
||||||
|
|
||||||
g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
|
g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
|
||||||
g_return_if_fail (curve[0] >= 0 && curve[0] <= 1 &&
|
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[2] >= 0 && curve[2] <= 1 &&
|
||||||
curve[3] >= 0 && curve[3] <= 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 = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||||
evdev_tool->pressure_curve[0].x = curve[0];
|
|
||||||
evdev_tool->pressure_curve[0].y = curve[1];
|
if (!graphene_point_equal (&p1, &evdev_tool->pressure_curve[0]) ||
|
||||||
evdev_tool->pressure_curve[1].x = curve[2];
|
!graphene_point_equal (&p2, &evdev_tool->pressure_curve[1]))
|
||||||
evdev_tool->pressure_curve[1].y = curve[3];
|
{
|
||||||
|
evdev_tool->pressure_curve[0] = p1;
|
||||||
|
evdev_tool->pressure_curve[1] = p2;
|
||||||
|
init_pressurecurve (evdev_tool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
double
|
||||||
meta_input_device_tool_native_translate_pressure_in_impl (ClutterInputDeviceTool *tool,
|
meta_input_device_tool_native_translate_pressure_in_impl (ClutterInputDeviceTool *tool,
|
||||||
double pressure)
|
double pressure)
|
||||||
{
|
{
|
||||||
MetaInputDeviceToolNative *evdev_tool;
|
MetaInputDeviceToolNative *evdev_tool;
|
||||||
|
double factor;
|
||||||
|
|
||||||
g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), pressure);
|
g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), pressure);
|
||||||
|
|
||||||
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
|
||||||
|
|
||||||
return calculate_bezier_position (CLAMP (pressure, 0, 1),
|
pressure = CLAMP (pressure, 0.0, 1.0);
|
||||||
evdev_tool->pressure_curve[0].x,
|
factor = meta_bezier_lookup (evdev_tool->bezier, pressure);
|
||||||
evdev_tool->pressure_curve[0].y,
|
|
||||||
evdev_tool->pressure_curve[1].x,
|
return pressure * factor;
|
||||||
evdev_tool->pressure_curve[1].y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <graphene.h>
|
#include <graphene.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
|
|
||||||
|
#include "backends/native/meta-bezier.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
@ -55,12 +56,15 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _MetaInputDeviceToolNative MetaInputDeviceToolNative;
|
typedef struct _MetaInputDeviceToolNative MetaInputDeviceToolNative;
|
||||||
typedef struct _MetaInputDeviceToolNativeClass MetaInputDeviceToolNativeClass;
|
typedef struct _MetaInputDeviceToolNativeClass MetaInputDeviceToolNativeClass;
|
||||||
|
|
||||||
|
#define N_PRESSURECURVE_POINTS 256
|
||||||
|
|
||||||
struct _MetaInputDeviceToolNative
|
struct _MetaInputDeviceToolNative
|
||||||
{
|
{
|
||||||
ClutterInputDeviceTool parent_instance;
|
ClutterInputDeviceTool parent_instance;
|
||||||
struct libinput_tablet_tool *tool;
|
struct libinput_tablet_tool *tool;
|
||||||
GHashTable *button_map;
|
GHashTable *button_map;
|
||||||
graphene_point_t pressure_curve[2];
|
graphene_point_t pressure_curve[2];
|
||||||
|
MetaBezier *bezier;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaInputDeviceToolNativeClass
|
struct _MetaInputDeviceToolNativeClass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user