Attempt to make cursor updates more efficient by queueing and performing once per frame, skip repaint trigger if a cursor update occurs
This commit is contained in:
parent
707710c4c7
commit
5192815098
|
|
@ -11,8 +11,6 @@ export class CursorManager {
|
|||
this._mainActor = mainActor;
|
||||
this._refreshRate = refreshRate;
|
||||
|
||||
this._changeHookFn = null;
|
||||
|
||||
// Set/destroyed by _enableCloningMouse/_disableCloningMouse
|
||||
this._cursorWantedVisible = null;
|
||||
this._cursorTracker = null;
|
||||
|
|
@ -131,8 +129,8 @@ export class CursorManager {
|
|||
} else {
|
||||
this._mainActor.add_actor(this._cursorActor);
|
||||
}
|
||||
this._cursorChangedConnection = this._cursorTracker.connect('cursor-changed', this._updateMouseSprite.bind(this));
|
||||
this._cursorVisibilityChangedConnection = this._cursorTracker.connect('visibility-changed', this._handleVisibilityChanged.bind(this));
|
||||
this._cursorChangedConnection = this._cursorTracker.connect('cursor-changed', this._queueSpriteUpdate.bind(this));
|
||||
this._cursorVisibilityChangedConnection = this._cursorTracker.connect('visibility-changed', this._queueVisibilityUpdate.bind(this));
|
||||
|
||||
// Some elements will occasionally appear above the cursor, so we periodically reset the actor stacking.
|
||||
// This could theoretically be fixed "better" by attaching to all events that might affect actor ordering,
|
||||
|
|
@ -144,11 +142,11 @@ export class CursorManager {
|
|||
}).bind(this));
|
||||
|
||||
const interval = 1000 / this._refreshRate;
|
||||
this._cursorWatch = this._cursorWatcher.addWatch(interval, this._updateMousePosition.bind(this));
|
||||
this._cursorWatch = this._cursorWatcher.addWatch(interval, this._queuePositionUpdate.bind(this));
|
||||
|
||||
const [x, y] = global.get_pointer();
|
||||
this._updateMousePosition(x, y);
|
||||
this._updateMouseSprite();
|
||||
this._queuePositionUpdate(x, y);
|
||||
this._queueSpriteUpdate();
|
||||
}
|
||||
|
||||
if (this._cursorTracker.set_keep_focus_while_hidden) {
|
||||
|
|
@ -203,34 +201,58 @@ export class CursorManager {
|
|||
}
|
||||
}
|
||||
|
||||
_updateMousePosition(x, y) {
|
||||
this._cursorActor.set_position(x, y);
|
||||
_queuePositionUpdate(x, y) {
|
||||
this._queued_cursor_position = [x, y];
|
||||
}
|
||||
|
||||
_updateMouseSprite() {
|
||||
const sprite = this._cursorTracker.get_sprite();
|
||||
if (sprite) {
|
||||
this._cursorSprite.content.texture = sprite;
|
||||
this._cursorSprite.show();
|
||||
} else {
|
||||
this._cursorSprite.hide();
|
||||
_queueSpriteUpdate() {
|
||||
this._queued_sprite_update = true;
|
||||
}
|
||||
|
||||
_queueVisibilityUpdate() {
|
||||
this._cursorTrackerSetPointerVisibleBound(false);
|
||||
this._queued_visibility_update = true;
|
||||
this._queueSpriteUpdate();
|
||||
}
|
||||
|
||||
handleNewFrame() {
|
||||
let redraw = false;
|
||||
if (this._queued_cursor_position) {
|
||||
const [x, y] = this._queued_cursor_position;
|
||||
this._cursorActor.set_position(x, y);
|
||||
this._queued_cursor_position = null;
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
const [xHot, yHot] = this._cursorTracker.get_hot();
|
||||
this._cursorSprite.set({
|
||||
translation_x: -xHot,
|
||||
translation_y: -yHot,
|
||||
});
|
||||
}
|
||||
if (this._queued_sprite_update) {
|
||||
const sprite = this._cursorTracker.get_sprite();
|
||||
if (sprite) {
|
||||
this._cursorSprite.content.texture = sprite;
|
||||
this._cursorSprite.show();
|
||||
} else {
|
||||
this._cursorSprite.hide();
|
||||
}
|
||||
|
||||
const [xHot, yHot] = this._cursorTracker.get_hot();
|
||||
this._cursorSprite.set({
|
||||
translation_x: -xHot,
|
||||
translation_y: -yHot,
|
||||
});
|
||||
this._queued_sprite_update = false;
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
_handleVisibilityChanged() {
|
||||
this._cursorTrackerSetPointerVisibleBound(false);
|
||||
this._updateMouseSprite();
|
||||
if (this._queued_visibility_update) {
|
||||
this._queued_visibility_update = false;
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
return redraw;
|
||||
}
|
||||
|
||||
// updates the stacking and other attributes that are hard to track and may periodically get out of sync
|
||||
_periodicReset() {
|
||||
this._handleVisibilityChanged();
|
||||
this._queueVisibilityUpdate();
|
||||
this._mainActor.set_child_above_sibling(this._cursorActor, null);
|
||||
|
||||
// some other processes are uninhibiting when they shouldn't, so we need to re-inhibit here
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this._disable_anti_aliasing_binding = null;
|
||||
this._optimal_monitor_config_binding = null;
|
||||
this._headset_as_primary_binding = null;
|
||||
this._redraw_timeline = null;
|
||||
|
||||
if (!Globals.logger) {
|
||||
Globals.logger = new Logger({
|
||||
|
|
@ -207,7 +208,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
try {
|
||||
const targetMonitor = this._target_monitor.monitor;
|
||||
const refreshRate = targetMonitor.refreshRate ?? 60;
|
||||
this._cursor_manager = new CursorManager(Main.layoutManager.uiGroup, refreshRate * 1.05);
|
||||
this._cursor_manager = new CursorManager(Main.layoutManager.uiGroup, refreshRate);
|
||||
this._cursor_manager.enable();
|
||||
|
||||
this._overlay = new St.Bin({ style: 'background-color: rgba(0, 0, 0, 1);'});
|
||||
|
|
@ -263,6 +264,17 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this._add_settings_keybinding('recenter-display-shortcut', this._recenter_display.bind(this));
|
||||
this._add_settings_keybinding('toggle-display-distance-shortcut', this._xr_effect._change_distance.bind(this._xr_effect));
|
||||
this._add_settings_keybinding('toggle-follow-shortcut', this._toggle_follow_mode.bind(this));
|
||||
|
||||
this._redraw_timeline = Clutter.Timeline.new_for_actor(Main.layoutManager.uiGroup, 1000);
|
||||
this._redraw_timeline.connect('new-frame', (() => {
|
||||
if (this._is_effect_running) {
|
||||
// if the cursor's frame handler triggered a redraw, we'll skip triggering it
|
||||
const skip_repaint = this._cursor_manager?.handleNewFrame();
|
||||
if (!skip_repaint) this._xr_effect?.queue_repaint();
|
||||
}
|
||||
}).bind(this));
|
||||
this._redraw_timeline.set_repeat_count(-1);
|
||||
this._redraw_timeline.start();
|
||||
} catch (e) {
|
||||
Globals.logger.log(`ERROR: BreezyDesktopExtension _effect_enable ${e.message}\n${e.stack}`);
|
||||
this._effect_disable();
|
||||
|
|
@ -372,6 +384,11 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
Globals.logger.log_debug('BreezyDesktopExtension _effect_disable');
|
||||
this._is_effect_running = false;
|
||||
|
||||
if (this._redraw_timeline) {
|
||||
this._redraw_timeline.stop();
|
||||
this._redraw_timeline = null;
|
||||
}
|
||||
|
||||
if (this._running_poller_id) {
|
||||
GLib.source_remove(this._running_poller_id);
|
||||
this._running_poller_id = undefined;
|
||||
|
|
|
|||
|
|
@ -292,8 +292,6 @@ export const XREffect = GObject.registerClass({
|
|||
this.customBannerImage = new Clutter.Image();
|
||||
this.customBannerImage.set_data(customBanner.get_pixels(), Cogl.PixelFormat.RGB_888,
|
||||
customBanner.width, customBanner.height, customBanner.rowstride);
|
||||
|
||||
this._redraw_timeline = null;
|
||||
}
|
||||
|
||||
_change_distance() {
|
||||
|
|
@ -341,13 +339,6 @@ export const XREffect = GObject.registerClass({
|
|||
this.setIntermittentUniformVariables = setIntermittentUniformVariables.bind(this);
|
||||
this.setIntermittentUniformVariables();
|
||||
|
||||
this._redraw_timeline = Clutter.Timeline.new_for_actor(this.get_actor(), 1000);
|
||||
this._redraw_timeline.connect('new-frame', (() => {
|
||||
this.queue_repaint();
|
||||
}).bind(this));
|
||||
this._redraw_timeline.set_repeat_count(-1);
|
||||
this._redraw_timeline.start();
|
||||
|
||||
this._uniforms_timeout_id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 250, (() => {
|
||||
this.setIntermittentUniformVariables();
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
|
|
@ -394,10 +385,6 @@ export const XREffect = GObject.registerClass({
|
|||
}
|
||||
|
||||
cleanup() {
|
||||
if (this._redraw_timeline) {
|
||||
this._redraw_timeline.stop();
|
||||
this._redraw_timeline = null;
|
||||
}
|
||||
if (this._uniforms_timeout_id) GLib.source_remove(this._uniforms_timeout_id);
|
||||
}
|
||||
});
|
||||
Loading…
Reference in New Issue