1
0
Fork 0
mutter-performance-source/src/backends/native/meta-cursor-renderer-native.c

1794 lines
60 KiB
C
Raw Normal View History

2014-04-22 19:15:11 +00:00
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2014 Red Hat
* Copyright 2020 DisplayLink (UK) Ltd.
2014-04-22 19:15:11 +00:00
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include "config.h"
#include "backends/native/meta-cursor-renderer-native.h"
2014-04-22 19:15:11 +00:00
#include <string.h>
2014-04-22 19:15:11 +00:00
#include <gbm.h>
#include <xf86drm.h>
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
#include <errno.h>
2014-04-22 19:15:11 +00:00
#include "backends/meta-backend-private.h"
#include "backends/meta-cursor-sprite-xcursor.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor.h"
#include "backends/meta-monitor-manager-private.h"
#include "backends/meta-output.h"
#include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-drm-buffer-gbm.h"
#include "backends/native/meta-kms-device.h"
#include "backends/native/meta-kms-update.h"
#include "backends/native/meta-kms.h"
#include "backends/native/meta-renderer-native.h"
#include "core/boxes-private.h"
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
#include "meta/boxes.h"
#include "meta/meta-backend.h"
#include "meta/util.h"
2014-04-22 19:15:11 +00:00
#ifdef HAVE_WAYLAND
#include "wayland/meta-cursor-sprite-wayland.h"
#include "wayland/meta-wayland-buffer.h"
#endif
#ifndef DRM_CAP_CURSOR_WIDTH
#define DRM_CAP_CURSOR_WIDTH 0x8
#endif
#ifndef DRM_CAP_CURSOR_HEIGHT
#define DRM_CAP_CURSOR_HEIGHT 0x9
#endif
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
/* When animating a cursor, we usually call drmModeSetCursor2 once per frame.
* Though, testing shows that we need to triple buffer the cursor buffer in
* order to avoid glitches when animating the cursor, at least when running on
* Intel. The reason for this might be (but is not confirmed to be) due to
* the user space gbm_bo cache, making us reuse and overwrite the kernel side
* buffer content before it was scanned out. To avoid this, we keep a user space
* reference to each buffer we set until at least one frame after it was drawn.
* In effect, this means we three active cursor gbm_bo's: one that that just has
* been set, one that was previously set and may or may not have been scanned
* out, and one pending that will be replaced if the cursor sprite changes.
*/
#define HW_CURSOR_BUFFER_COUNT 3
static GQuark quark_cursor_sprite = 0;
struct _MetaCursorRendererNative
{
MetaCursorRenderer parent;
};
2014-04-22 19:15:11 +00:00
struct _MetaCursorRendererNativePrivate
{
MetaBackend *backend;
gboolean hw_state_invalidated;
2014-04-22 19:15:11 +00:00
gboolean has_hw_cursor;
MetaCursorSprite *last_cursor;
guint animation_timeout_id;
};
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
typedef struct _MetaCursorRendererNativeGpuData
{
gboolean hw_cursor_broken;
uint64_t cursor_width;
uint64_t cursor_height;
} MetaCursorRendererNativeGpuData;
2014-04-22 19:15:11 +00:00
typedef enum _MetaCursorBufferState
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
META_CURSOR_BUFFER_STATE_NONE,
META_CURSOR_BUFFER_STATE_SET,
META_CURSOR_BUFFER_STATE_INVALIDATED,
} MetaCursorBufferState;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
typedef struct _MetaCursorNativeGpuState
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
MetaGpu *gpu;
unsigned int active_buffer_idx;
MetaCursorBufferState pending_buffer_state;
MetaDrmBuffer *buffers[HW_CURSOR_BUFFER_COUNT];
} MetaCursorNativeGpuState;
typedef struct _MetaCursorNativePrivate
{
GHashTable *gpu_states;
struct {
gboolean can_preprocess;
float current_relative_scale;
MetaMonitorTransform current_relative_transform;
} preprocess_state;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
} MetaCursorNativePrivate;
static GQuark quark_cursor_renderer_native_gpu_data = 0;
2014-04-22 19:15:11 +00:00
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER);
static void
realize_cursor_sprite (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
GList *gpus);
static MetaCursorNativeGpuState *
get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
MetaGpuKms *gpu_kms);
static MetaCursorNativeGpuState *
ensure_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
MetaGpuKms *gpu_kms);
static void
invalidate_cursor_gpu_state (MetaCursorSprite *cursor_sprite);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
static MetaCursorNativePrivate *
ensure_cursor_priv (MetaCursorSprite *cursor_sprite);
static MetaCursorNativePrivate *
get_cursor_priv (MetaCursorSprite *cursor_sprite);
static MetaCursorRendererNativeGpuData *
meta_cursor_renderer_native_gpu_data_from_gpu (MetaGpuKms *gpu_kms)
{
return g_object_get_qdata (G_OBJECT (gpu_kms),
quark_cursor_renderer_native_gpu_data);
}
static MetaCursorRendererNativeGpuData *
meta_create_cursor_renderer_native_gpu_data (MetaGpuKms *gpu_kms)
{
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
cursor_renderer_gpu_data = g_new0 (MetaCursorRendererNativeGpuData, 1);
g_object_set_qdata_full (G_OBJECT (gpu_kms),
quark_cursor_renderer_native_gpu_data,
cursor_renderer_gpu_data,
g_free);
return cursor_renderer_gpu_data;
}
2014-04-22 19:15:11 +00:00
static void
meta_cursor_renderer_native_finalize (GObject *object)
{
MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (renderer);
2014-04-22 19:15:11 +00:00
g_clear_handle_id (&priv->animation_timeout_id, g_source_remove);
2014-04-22 19:15:11 +00:00
G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
}
static unsigned int
get_pending_cursor_sprite_buffer_index (MetaCursorNativeGpuState *cursor_gpu_state)
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
return (cursor_gpu_state->active_buffer_idx + 1) % HW_CURSOR_BUFFER_COUNT;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
}
static MetaDrmBuffer *
get_pending_cursor_sprite_buffer (MetaCursorNativeGpuState *cursor_gpu_state)
{
unsigned int pending_buffer_idx;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
pending_buffer_idx =
get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
return cursor_gpu_state->buffers[pending_buffer_idx];
}
static MetaDrmBuffer *
get_active_cursor_sprite_buffer (MetaCursorNativeGpuState *cursor_gpu_state)
{
return cursor_gpu_state->buffers[cursor_gpu_state->active_buffer_idx];
}
static void
set_pending_cursor_sprite_buffer (MetaCursorSprite *cursor_sprite,
MetaGpuKms *gpu_kms,
MetaDrmBuffer *buffer)
{
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
MetaCursorNativePrivate *cursor_priv;
MetaCursorNativeGpuState *cursor_gpu_state;
unsigned int pending_buffer_idx;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
cursor_priv = ensure_cursor_priv (cursor_sprite);
cursor_gpu_state = ensure_cursor_gpu_state (cursor_priv, gpu_kms);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
pending_buffer_idx =
get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
cursor_gpu_state->buffers[pending_buffer_idx] = buffer;
cursor_gpu_state->pending_buffer_state = META_CURSOR_BUFFER_STATE_SET;
}
static void
calculate_crtc_cursor_hotspot (MetaCursorSprite *cursor_sprite,
int *cursor_hotspot_x,
int *cursor_hotspot_y)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
int hot_x, hot_y;
int width, height;
float scale;
MetaMonitorTransform transform;
scale = cursor_priv->preprocess_state.current_relative_scale;
transform = cursor_priv->preprocess_state.current_relative_transform;
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
width = meta_cursor_sprite_get_width (cursor_sprite);
height = meta_cursor_sprite_get_height (cursor_sprite);
meta_monitor_transform_transform_point (transform,
width, height,
hot_x, hot_y,
&hot_x, &hot_y);
*cursor_hotspot_x = (int) roundf (hot_x * scale);
*cursor_hotspot_y = (int) roundf (hot_y * scale);
}
2014-04-22 19:15:11 +00:00
static void
set_crtc_cursor (MetaCursorRendererNative *native,
MetaKmsUpdate *kms_update,
MetaCrtcKms *crtc_kms,
int x,
int y,
MetaCursorSprite *cursor_sprite)
2014-04-22 19:15:11 +00:00
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
MetaCrtc *crtc = META_CRTC (crtc_kms);
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
MetaCursorNativeGpuState *cursor_gpu_state =
get_cursor_gpu_state (cursor_priv, gpu_kms);
MetaKmsCrtc *kms_crtc;
MetaKmsDevice *kms_device;
MetaKmsPlane *cursor_plane;
MetaDrmBuffer *buffer;
int cursor_width, cursor_height;
MetaFixed16Rectangle src_rect;
MetaRectangle dst_rect;
MetaDrmBuffer *crtc_buffer;
MetaKmsAssignPlaneFlag flags;
int cursor_hotspot_x;
int cursor_hotspot_y;
MetaKmsPlaneAssignment *plane_assignment;
if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
buffer = get_pending_cursor_sprite_buffer (cursor_gpu_state);
else
buffer = get_active_cursor_sprite_buffer (cursor_gpu_state);
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
kms_device = meta_kms_crtc_get_device (kms_crtc);
cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
g_return_if_fail (cursor_plane);
cursor_width = cursor_renderer_gpu_data->cursor_width;
cursor_height = cursor_renderer_gpu_data->cursor_height;
src_rect = (MetaFixed16Rectangle) {
.x = meta_fixed_16_from_int (0),
.y = meta_fixed_16_from_int (0),
.width = meta_fixed_16_from_int (cursor_width),
.height = meta_fixed_16_from_int (cursor_height),
};
dst_rect = (MetaRectangle) {
.x = x,
.y = y,
.width = cursor_width,
.height = cursor_height,
};
2014-04-22 19:15:11 +00:00
flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
if (!priv->hw_state_invalidated && buffer == crtc_buffer)
flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
2014-04-22 19:15:11 +00:00
plane_assignment = meta_kms_update_assign_plane (kms_update,
kms_crtc,
cursor_plane,
buffer,
src_rect,
dst_rect,
flags);
calculate_crtc_cursor_hotspot (cursor_sprite,
&cursor_hotspot_x,
&cursor_hotspot_y);
meta_kms_plane_assignment_set_cursor_hotspot (plane_assignment,
cursor_hotspot_x,
cursor_hotspot_y);
meta_crtc_kms_set_cursor_renderer_private (crtc_kms, buffer);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
{
cursor_gpu_state->active_buffer_idx =
(cursor_gpu_state->active_buffer_idx + 1) % HW_CURSOR_BUFFER_COUNT;
cursor_gpu_state->pending_buffer_state = META_CURSOR_BUFFER_STATE_NONE;
}
}
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
static void
unset_crtc_cursor (MetaCursorRendererNative *native,
MetaKmsUpdate *kms_update,
MetaCrtcKms *crtc_kms)
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
MetaKmsCrtc *kms_crtc;
MetaKmsDevice *kms_device;
MetaKmsPlane *cursor_plane;
MetaDrmBuffer *crtc_buffer;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
if (!priv->hw_state_invalidated && !crtc_buffer)
return;
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
kms_device = meta_kms_crtc_get_device (kms_crtc);
cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
if (cursor_plane)
meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
meta_crtc_kms_set_cursor_renderer_private (crtc_kms, NULL);
2014-04-22 19:15:11 +00:00
}
static float
calculate_cursor_crtc_sprite_scale (MetaCursorSprite *cursor_sprite,
MetaLogicalMonitor *logical_monitor)
{
if (meta_is_stage_views_scaled ())
{
return (meta_logical_monitor_get_scale (logical_monitor) *
meta_cursor_sprite_get_texture_scale (cursor_sprite));
}
else
{
return 1.0;
}
}
typedef struct
{
MetaCursorRendererNative *in_cursor_renderer_native;
MetaLogicalMonitor *in_logical_monitor;
graphene_rect_t in_local_cursor_rect;
MetaCursorSprite *in_cursor_sprite;
gboolean out_painted;
} UpdateCrtcCursorData;
static gboolean
update_monitor_crtc_cursor (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorCrtcMode *monitor_crtc_mode,
gpointer user_data,
GError **error)
{
UpdateCrtcCursorData *data = user_data;
MetaCursorRendererNative *cursor_renderer_native =
data->in_cursor_renderer_native;
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaCrtc *crtc;
MetaGpuKms *gpu_kms;
MetaKmsDevice *kms_device;
MetaKms *kms;
MetaKmsUpdate *kms_update;
MetaMonitorTransform transform;
const MetaCrtcModeInfo *crtc_mode_info;
graphene_rect_t scaled_crtc_rect;
float scale;
int crtc_x, crtc_y;
int crtc_width, crtc_height;
if (meta_is_stage_views_scaled ())
scale = meta_logical_monitor_get_scale (data->in_logical_monitor);
else
scale = 1.0;
transform = meta_logical_monitor_get_transform (data->in_logical_monitor);
transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
meta_monitor_calculate_crtc_pos (monitor, monitor_mode,
monitor_crtc_mode->output,
transform,
&crtc_x, &crtc_y);
crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
if (meta_monitor_transform_is_rotated (transform))
{
crtc_width = crtc_mode_info->height;
crtc_height = crtc_mode_info->width;
}
else
{
crtc_width = crtc_mode_info->width;
crtc_height = crtc_mode_info->height;
}
scaled_crtc_rect = (graphene_rect_t) {
.origin = {
.x = crtc_x / scale,
.y = crtc_y / scale
},
.size = {
.width = crtc_width / scale,
.height = crtc_height / scale
},
};
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
kms = meta_kms_device_get_kms (kms_device);
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
if (priv->has_hw_cursor &&
graphene_rect_intersection (&scaled_crtc_rect,
&data->in_local_cursor_rect,
NULL))
{
MetaMonitorTransform inverted_transform;
MetaRectangle cursor_rect;
CoglTexture *texture;
float crtc_cursor_x, crtc_cursor_y;
float cursor_crtc_scale;
int tex_width, tex_height;
crtc_cursor_x = (data->in_local_cursor_rect.origin.x -
scaled_crtc_rect.origin.x) * scale;
crtc_cursor_y = (data->in_local_cursor_rect.origin.y -
scaled_crtc_rect.origin.y) * scale;
texture = meta_cursor_sprite_get_cogl_texture (data->in_cursor_sprite);
tex_width = cogl_texture_get_width (texture);
tex_height = cogl_texture_get_height (texture);
cursor_crtc_scale =
calculate_cursor_crtc_sprite_scale (data->in_cursor_sprite,
data->in_logical_monitor);
cursor_rect = (MetaRectangle) {
.x = floorf (crtc_cursor_x),
.y = floorf (crtc_cursor_y),
.width = roundf (tex_width * cursor_crtc_scale),
.height = roundf (tex_height * cursor_crtc_scale)
};
inverted_transform = meta_monitor_transform_invert (transform);
meta_rectangle_transform (&cursor_rect,
inverted_transform,
crtc_mode_info->width,
crtc_mode_info->height,
&cursor_rect);
set_crtc_cursor (data->in_cursor_renderer_native,
kms_update,
META_CRTC_KMS (crtc),
cursor_rect.x,
cursor_rect.y,
data->in_cursor_sprite);
data->out_painted = data->out_painted || TRUE;
}
else
{
unset_crtc_cursor (data->in_cursor_renderer_native,
kms_update,
META_CRTC_KMS (crtc));
}
return TRUE;
}
static void
disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
const GError *error)
{
MetaCrtcKms *crtc_kms = meta_crtc_kms_from_kms_crtc (kms_crtc);
MetaCrtc *crtc = META_CRTC (crtc_kms);
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
g_warning ("Failed to set hardware cursor (%s), "
"using OpenGL from now on",
error->message);
cursor_renderer_gpu_data->hw_cursor_broken = TRUE;
}
2014-04-22 19:15:11 +00:00
static void
update_hw_cursor (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite)
2014-04-22 19:15:11 +00:00
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
2014-04-22 19:15:11 +00:00
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaBackend *backend = priv->backend;
MetaBackendNative *backend_native = META_BACKEND_NATIVE (priv->backend);
MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *l;
graphene_rect_t rect;
gboolean painted = FALSE;
g_autoptr (MetaKmsFeedback) feedback = NULL;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (cursor_sprite)
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
else
rect = GRAPHENE_RECT_INIT_ZERO;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
2014-04-22 19:15:11 +00:00
{
MetaLogicalMonitor *logical_monitor = l->data;
UpdateCrtcCursorData data;
GList *monitors;
GList *k;
data = (UpdateCrtcCursorData) {
.in_cursor_renderer_native = native,
.in_logical_monitor = logical_monitor,
.in_local_cursor_rect = (graphene_rect_t) {
.origin = {
.x = rect.origin.x - logical_monitor->rect.x,
.y = rect.origin.y - logical_monitor->rect.y
},
.size = rect.size
},
.in_cursor_sprite = cursor_sprite,
};
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (k = monitors; k; k = k->next)
2014-04-22 19:15:11 +00:00
{
MetaMonitor *monitor = k->data;
MetaMonitorMode *monitor_mode;
monitor_mode = meta_monitor_get_current_mode (monitor);
meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
update_monitor_crtc_cursor,
&data,
NULL);
2014-04-22 19:15:11 +00:00
}
painted = painted || data.out_painted;
2014-04-22 19:15:11 +00:00
}
feedback = meta_kms_post_pending_updates_sync (kms);
if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED)
{
for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next)
{
MetaKmsPlaneFeedback *plane_feedback = l->data;
if (!g_error_matches (plane_feedback->error,
G_IO_ERROR,
G_IO_ERROR_PERMISSION_DENIED))
{
disable_hw_cursor_for_crtc (plane_feedback->crtc,
plane_feedback->error);
}
}
priv->has_hw_cursor = FALSE;
}
priv->hw_state_invalidated = FALSE;
if (painted)
meta_cursor_renderer_emit_painted (renderer, cursor_sprite);
2014-04-22 19:15:11 +00:00
}
static gboolean
has_valid_cursor_sprite_buffer (MetaCursorSprite *cursor_sprite,
MetaGpuKms *gpu_kms)
2014-04-22 19:15:11 +00:00
{
MetaCursorNativePrivate *cursor_priv;
MetaCursorNativeGpuState *cursor_gpu_state;
2014-04-22 19:15:11 +00:00
cursor_priv = get_cursor_priv (cursor_sprite);
if (!cursor_priv)
return FALSE;
cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms);
if (!cursor_gpu_state)
return FALSE;
switch (cursor_gpu_state->pending_buffer_state)
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
case META_CURSOR_BUFFER_STATE_NONE:
return get_active_cursor_sprite_buffer (cursor_gpu_state) != NULL;
case META_CURSOR_BUFFER_STATE_SET:
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
return TRUE;
case META_CURSOR_BUFFER_STATE_INVALIDATED:
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
return FALSE;
}
g_assert_not_reached ();
return FALSE;
}
static void
set_can_preprocess (MetaCursorSprite *cursor_sprite,
float scale,
MetaMonitorTransform transform)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
cursor_priv->preprocess_state.current_relative_scale = scale;
cursor_priv->preprocess_state.current_relative_transform = transform;
cursor_priv->preprocess_state.can_preprocess = TRUE;
invalidate_cursor_gpu_state (cursor_sprite);
}
static void
unset_can_preprocess (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
memset (&cursor_priv->preprocess_state,
0,
sizeof (cursor_priv->preprocess_state));
cursor_priv->preprocess_state.can_preprocess = FALSE;
invalidate_cursor_gpu_state (cursor_sprite);
}
static gboolean
get_can_preprocess (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
return cursor_priv->preprocess_state.can_preprocess;
}
static float
get_current_relative_scale (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
return cursor_priv->preprocess_state.current_relative_scale;
}
static MetaMonitorTransform
get_current_relative_transform (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
return cursor_priv->preprocess_state.current_relative_transform;
}
static void
has_cursor_plane (MetaLogicalMonitor *logical_monitor,
MetaMonitor *monitor,
MetaOutput *output,
MetaCrtc *crtc,
gpointer user_data)
{
gboolean *has_cursor_planes = user_data;
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
*has_cursor_planes &= !!meta_kms_device_get_cursor_plane_for (kms_device,
kms_crtc);
}
static gboolean
crtcs_has_cursor_planes (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNative *cursor_renderer_native =
META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaBackend *backend = priv->backend;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *l;
graphene_rect_t cursor_rect;
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
MetaRectangle logical_monitor_layout;
graphene_rect_t logical_monitor_rect;
gboolean has_cursor_planes;
logical_monitor_layout =
meta_logical_monitor_get_layout (logical_monitor);
logical_monitor_rect =
meta_rectangle_to_graphene_rect (&logical_monitor_layout);
if (!graphene_rect_intersection (&cursor_rect, &logical_monitor_rect,
NULL))
continue;
has_cursor_planes = TRUE;
meta_logical_monitor_foreach_crtc (logical_monitor,
has_cursor_plane,
&has_cursor_planes);
if (!has_cursor_planes)
return FALSE;
}
return TRUE;
}
static gboolean
get_common_crtc_sprite_scale_for_logical_monitors (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
float *out_scale)
{
MetaCursorRendererNative *cursor_renderer_native =
META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaBackend *backend = priv->backend;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
graphene_rect_t cursor_rect;
float scale = 1.0;
gboolean has_visible_crtc_sprite = FALSE;
GList *logical_monitors;
GList *l;
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
graphene_rect_t logical_monitor_rect =
meta_rectangle_to_graphene_rect (&logical_monitor->rect);
float tmp_scale;
if (!graphene_rect_intersection (&cursor_rect,
&logical_monitor_rect,
NULL))
continue;
tmp_scale =
calculate_cursor_crtc_sprite_scale (cursor_sprite, logical_monitor);
if (has_visible_crtc_sprite && scale != tmp_scale)
return FALSE;
has_visible_crtc_sprite = TRUE;
scale = tmp_scale;
}
if (!has_visible_crtc_sprite)
return FALSE;
*out_scale = scale;
return TRUE;
}
static gboolean
get_common_crtc_sprite_transform_for_logical_monitors (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
MetaMonitorTransform *out_transform)
{
MetaCursorRendererNative *cursor_renderer_native =
META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaBackend *backend = priv->backend;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
graphene_rect_t cursor_rect;
MetaMonitorTransform transform = META_MONITOR_TRANSFORM_NORMAL;
gboolean has_visible_crtc_sprite = FALSE;
GList *logical_monitors;
GList *l;
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
graphene_rect_t logical_monitor_rect =
meta_rectangle_to_graphene_rect (&logical_monitor->rect);
MetaMonitorTransform logical_transform, tmp_transform;
GList *monitors, *l_mon;
if (!graphene_rect_intersection (&cursor_rect,
&logical_monitor_rect,
NULL))
continue;
logical_transform = meta_logical_monitor_get_transform (logical_monitor);
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (l_mon = monitors; l_mon; l_mon = l_mon->next)
{
MetaMonitor *monitor = l_mon->data;
tmp_transform = meta_monitor_transform_relative_transform (
meta_cursor_sprite_get_texture_transform (cursor_sprite),
meta_monitor_logical_to_crtc_transform (monitor, logical_transform));
if (has_visible_crtc_sprite && transform != tmp_transform)
return FALSE;
has_visible_crtc_sprite = TRUE;
transform = tmp_transform;
}
}
if (!has_visible_crtc_sprite)
return FALSE;
*out_transform = transform;
return TRUE;
}
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
static gboolean
should_have_hw_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
GList *gpus)
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
MetaCursorRendererNative *cursor_renderer_native =
META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
CoglTexture *texture;
MetaMonitorTransform transform;
float scale;
GList *l;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (!cursor_sprite)
2014-04-22 19:15:11 +00:00
return FALSE;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (meta_backend_is_hw_cursors_inhibited (priv->backend))
return FALSE;
for (l = gpus; l; l = l->next)
{
MetaGpuKms *gpu_kms = l->data;
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
if (!cursor_renderer_gpu_data)
return FALSE;
if (cursor_renderer_gpu_data->hw_cursor_broken)
return FALSE;
if (!has_valid_cursor_sprite_buffer (cursor_sprite, gpu_kms))
return FALSE;
}
if (!crtcs_has_cursor_planes (renderer, cursor_sprite))
return FALSE;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture)
return FALSE;
if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer,
cursor_sprite,
&scale))
return FALSE;
if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer,
cursor_sprite,
&transform))
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
return FALSE;
if (G_APPROX_VALUE (scale, 1.f, FLT_EPSILON) &&
transform == META_MONITOR_TRANSFORM_NORMAL)
return TRUE;
else
return get_can_preprocess (cursor_sprite);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
return TRUE;
2014-04-22 19:15:11 +00:00
}
static gboolean
meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer);
priv->animation_timeout_id = 0;
meta_cursor_sprite_tick_frame (cursor_sprite);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
meta_cursor_renderer_force_update (renderer);
return G_SOURCE_REMOVE;
}
static void
maybe_schedule_cursor_sprite_animation_frame (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
gboolean cursor_change;
guint delay;
cursor_change = cursor_sprite != priv->last_cursor;
priv->last_cursor = cursor_sprite;
if (!cursor_change && priv->animation_timeout_id)
return;
g_clear_handle_id (&priv->animation_timeout_id, g_source_remove);
if (cursor_sprite && meta_cursor_sprite_is_animated (cursor_sprite))
{
delay = meta_cursor_sprite_get_current_frame_time (cursor_sprite);
if (delay == 0)
return;
priv->animation_timeout_id =
g_timeout_add (delay,
(GSourceFunc) meta_cursor_renderer_native_update_animation,
native);
g_source_set_name_by_id (priv->animation_timeout_id,
"[mutter] meta_cursor_renderer_native_update_animation");
}
}
static GList *
calculate_cursor_sprite_gpus (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
MetaBackend *backend = priv->backend;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *gpus = NULL;
GList *logical_monitors;
GList *l;
graphene_rect_t cursor_rect;
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
MetaRectangle logical_monitor_layout;
graphene_rect_t logical_monitor_rect;
GList *monitors, *l_mon;
logical_monitor_layout =
meta_logical_monitor_get_layout (logical_monitor);
logical_monitor_rect =
meta_rectangle_to_graphene_rect (&logical_monitor_layout);
if (!graphene_rect_intersection (&cursor_rect, &logical_monitor_rect,
NULL))
continue;
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (l_mon = monitors; l_mon; l_mon = l_mon->next)
{
MetaMonitor *monitor = l_mon->data;
MetaGpu *gpu;
gpu = meta_monitor_get_gpu (monitor);
if (!g_list_find (gpus, gpu))
gpus = g_list_prepend (gpus, gpu);
}
}
return gpus;
}
static gboolean
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
2014-04-22 19:15:11 +00:00
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
g_autoptr (GList) gpus = NULL;
2014-04-22 19:15:11 +00:00
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (cursor_sprite)
{
meta_cursor_sprite_realize_texture (cursor_sprite);
gpus = calculate_cursor_sprite_gpus (renderer, cursor_sprite);
realize_cursor_sprite (renderer, cursor_sprite, gpus);
}
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
maybe_schedule_cursor_sprite_animation_frame (native, cursor_sprite);
priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite, gpus);
update_hw_cursor (native, cursor_sprite);
return (priv->has_hw_cursor ||
!cursor_sprite ||
!meta_cursor_sprite_get_cogl_texture (cursor_sprite));
2014-04-22 19:15:11 +00:00
}
static void
unset_crtc_cursor_renderer_privates (MetaGpu *gpu,
MetaDrmBuffer *buffer)
{
GList *l;
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
{
MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data);
MetaDrmBuffer *crtc_buffer;
crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
if (buffer == crtc_buffer)
meta_crtc_kms_set_cursor_renderer_private (crtc_kms, NULL);
}
}
static void
cursor_gpu_state_free (MetaCursorNativeGpuState *cursor_gpu_state)
{
int i;
MetaDrmBuffer *active_buffer;
active_buffer = get_active_cursor_sprite_buffer (cursor_gpu_state);
if (active_buffer)
unset_crtc_cursor_renderer_privates (cursor_gpu_state->gpu,
active_buffer);
for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++)
g_clear_object (&cursor_gpu_state->buffers[i]);
g_free (cursor_gpu_state);
}
static MetaCursorNativeGpuState *
get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
MetaGpuKms *gpu_kms)
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
return g_hash_table_lookup (cursor_priv->gpu_states, gpu_kms);
}
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
static MetaCursorNativeGpuState *
ensure_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
MetaGpuKms *gpu_kms)
{
MetaCursorNativeGpuState *cursor_gpu_state;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms);
if (cursor_gpu_state)
return cursor_gpu_state;
cursor_gpu_state = g_new0 (MetaCursorNativeGpuState, 1);
cursor_gpu_state->gpu = META_GPU (gpu_kms);
g_hash_table_insert (cursor_priv->gpu_states, gpu_kms, cursor_gpu_state);
return cursor_gpu_state;
}
static void
invalidate_cursor_gpu_state (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
GHashTableIter iter;
MetaCursorNativeGpuState *cursor_gpu_state;
g_hash_table_iter_init (&iter, cursor_priv->gpu_states);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &cursor_gpu_state))
{
unsigned int pending_buffer_idx;
pending_buffer_idx = get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
g_clear_object (&cursor_gpu_state->buffers[pending_buffer_idx]);
cursor_gpu_state->pending_buffer_state =
META_CURSOR_BUFFER_STATE_INVALIDATED;
}
}
static void
on_cursor_sprite_texture_changed (MetaCursorSprite *cursor_sprite)
{
invalidate_cursor_gpu_state (cursor_sprite);
}
static void
cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
{
g_hash_table_destroy (cursor_priv->gpu_states);
g_free (cursor_priv);
}
static MetaCursorNativePrivate *
get_cursor_priv (MetaCursorSprite *cursor_sprite)
{
return g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
}
static MetaCursorNativePrivate *
ensure_cursor_priv (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
cursor_priv = get_cursor_priv (cursor_sprite);
if (cursor_priv)
return cursor_priv;
cursor_priv = g_new0 (MetaCursorNativePrivate, 1);
cursor_priv->gpu_states =
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
(GDestroyNotify) cursor_gpu_state_free);
g_object_set_qdata_full (G_OBJECT (cursor_sprite),
quark_cursor_sprite,
cursor_priv,
(GDestroyNotify) cursor_priv_free);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
g_signal_connect (cursor_sprite, "texture-changed",
G_CALLBACK (on_cursor_sprite_texture_changed), NULL);
unset_can_preprocess (cursor_sprite);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
return cursor_priv;
}
static void
load_cursor_sprite_gbm_buffer_for_gpu (MetaCursorRendererNative *native,
MetaGpuKms *gpu_kms,
MetaCursorSprite *cursor_sprite,
uint8_t *pixels,
uint width,
uint height,
int rowstride,
uint32_t gbm_format)
{
uint64_t cursor_width, cursor_height;
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
struct gbm_device *gbm_device;
cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
if (!cursor_renderer_gpu_data)
return;
cursor_width = (uint64_t) cursor_renderer_gpu_data->cursor_width;
cursor_height = (uint64_t) cursor_renderer_gpu_data->cursor_height;
if (width > cursor_width || height > cursor_height)
{
meta_warning ("Invalid theme cursor size (must be at most %ux%u)",
(unsigned int)cursor_width, (unsigned int)cursor_height);
return;
}
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
if (gbm_device_is_format_supported (gbm_device, gbm_format,
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
{
MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
struct gbm_bo *bo;
uint8_t buf[4 * cursor_width * cursor_height];
uint i;
g_autoptr (GError) error = NULL;
MetaDrmBufferGbm *buffer_gbm;
bo = gbm_bo_create (gbm_device, cursor_width, cursor_height,
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (!bo)
{
meta_warning ("Failed to allocate HW cursor buffer");
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
return;
}
memset (buf, 0, sizeof(buf));
for (i = 0; i < height; i++)
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (gbm_bo_write (bo, buf, cursor_width * cursor_height * 4) != 0)
{
meta_warning ("Failed to write cursors buffer data: %s",
g_strerror (errno));
gbm_bo_destroy (bo);
return;
}
buffer_gbm = meta_drm_buffer_gbm_new_take (kms_device, bo, FALSE, &error);
if (!buffer_gbm)
{
meta_warning ("Failed to create DRM buffer wrapper: %s",
error->message);
gbm_bo_destroy (bo);
return;
}
set_pending_cursor_sprite_buffer (cursor_sprite, gpu_kms,
META_DRM_BUFFER (buffer_gbm));
}
else
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
meta_warning ("HW cursor for format %d not supported", gbm_format);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
}
}
static gboolean
is_cursor_hw_state_valid (MetaCursorSprite *cursor_sprite,
MetaGpuKms *gpu_kms)
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
{
MetaCursorNativePrivate *cursor_priv;
MetaCursorNativeGpuState *cursor_gpu_state;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
cursor_priv = get_cursor_priv (cursor_sprite);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (!cursor_priv)
return FALSE;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms);
if (!cursor_gpu_state)
return FALSE;
switch (cursor_gpu_state->pending_buffer_state)
{
case META_CURSOR_BUFFER_STATE_SET:
case META_CURSOR_BUFFER_STATE_NONE:
return TRUE;
case META_CURSOR_BUFFER_STATE_INVALIDATED:
return FALSE;
}
g_assert_not_reached ();
return FALSE;
}
static gboolean
is_cursor_scale_and_transform_valid (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaMonitorTransform transform;
float scale;
if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer,
cursor_sprite,
&scale))
return FALSE;
if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer,
cursor_sprite,
&transform))
return FALSE;
return (scale == get_current_relative_scale (cursor_sprite) &&
transform == get_current_relative_transform (cursor_sprite));
}
static cairo_surface_t *
scale_and_transform_cursor_sprite_cpu (uint8_t *pixels,
int width,
int height,
int rowstride,
float scale,
MetaMonitorTransform transform)
{
cairo_t *cr;
cairo_surface_t *source_surface;
cairo_surface_t *target_surface;
int image_width;
int image_height;
image_width = ceilf (width * scale);
image_height = ceilf (height * scale);
target_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
image_width,
image_height);
cr = cairo_create (target_surface);
if (transform != META_MONITOR_TRANSFORM_NORMAL)
{
cairo_translate (cr, 0.5 * image_width, 0.5 * image_height);
switch (transform)
{
case META_MONITOR_TRANSFORM_90:
cairo_rotate (cr, M_PI * 1.5);
break;
case META_MONITOR_TRANSFORM_180:
cairo_rotate (cr, M_PI);
break;
case META_MONITOR_TRANSFORM_270:
cairo_rotate (cr, M_PI * 0.5);
break;
case META_MONITOR_TRANSFORM_FLIPPED:
cairo_scale (cr, 1, -1);
break;
case META_MONITOR_TRANSFORM_FLIPPED_90:
cairo_rotate (cr, M_PI * 1.5);
cairo_scale (cr, -1, 1);
break;
case META_MONITOR_TRANSFORM_FLIPPED_180:
cairo_rotate (cr, M_PI);
cairo_scale (cr, 1, -1);
break;
case META_MONITOR_TRANSFORM_FLIPPED_270:
cairo_rotate (cr, M_PI * 0.5);
cairo_scale (cr, -1, 1);
break;
case META_MONITOR_TRANSFORM_NORMAL:
g_assert_not_reached ();
}
cairo_translate (cr, -0.5 * image_width, -0.5 * image_height);
}
cairo_scale (cr, scale, scale);
source_surface = cairo_image_surface_create_for_data (pixels,
CAIRO_FORMAT_ARGB32,
width,
height,
rowstride);
cairo_set_source_surface (cr, source_surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (source_surface);
return target_surface;
}
static void
load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native,
MetaGpuKms *gpu_kms,
MetaCursorSprite *cursor_sprite,
float relative_scale,
MetaMonitorTransform relative_transform,
uint8_t *data,
int width,
int height,
int rowstride,
uint32_t gbm_format)
{
if (!G_APPROX_VALUE (relative_scale, 1.f, FLT_EPSILON) ||
relative_transform != META_MONITOR_TRANSFORM_NORMAL)
{
cairo_surface_t *surface;
surface = scale_and_transform_cursor_sprite_cpu (data,
width,
height,
rowstride,
relative_scale,
relative_transform);
load_cursor_sprite_gbm_buffer_for_gpu (native,
gpu_kms,
cursor_sprite,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_width (surface),
cairo_image_surface_get_width (surface),
cairo_image_surface_get_stride (surface),
gbm_format);
cairo_surface_destroy (surface);
}
else
{
load_cursor_sprite_gbm_buffer_for_gpu (native,
gpu_kms,
cursor_sprite,
data,
width,
height,
rowstride,
gbm_format);
}
}
#ifdef HAVE_WAYLAND
static void
realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
MetaGpuKms *gpu_kms,
MetaCursorSpriteWayland *sprite_wayland)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_wayland);
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
uint64_t cursor_width, cursor_height;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
CoglTexture *texture;
uint width, height;
MetaWaylandBuffer *buffer;
struct wl_resource *buffer_resource;
struct wl_shm_buffer *shm_buffer;
cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
return;
if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms) &&
is_cursor_scale_and_transform_valid (renderer, cursor_sprite))
return;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
buffer = meta_cursor_sprite_wayland_get_buffer (sprite_wayland);
if (!buffer)
return;
buffer_resource = meta_wayland_buffer_get_resource (buffer);
if (!buffer_resource)
return;
ensure_cursor_priv (cursor_sprite);
shm_buffer = wl_shm_buffer_get (buffer_resource);
if (shm_buffer)
{
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
uint8_t *buffer_data;
float relative_scale;
MetaMonitorTransform relative_transform;
uint32_t gbm_format;
if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer,
cursor_sprite,
&relative_scale))
{
unset_can_preprocess (cursor_sprite);
return;
}
if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer,
cursor_sprite,
&relative_transform))
{
unset_can_preprocess (cursor_sprite);
return;
}
set_can_preprocess (cursor_sprite,
relative_scale,
relative_transform);
wl_shm_buffer_begin_access (shm_buffer);
buffer_data = wl_shm_buffer_get_data (shm_buffer);
width = wl_shm_buffer_get_width (shm_buffer);
height = wl_shm_buffer_get_height (shm_buffer);
switch (wl_shm_buffer_get_format (shm_buffer))
{
case WL_SHM_FORMAT_ARGB8888:
gbm_format = GBM_FORMAT_ARGB8888;
break;
case WL_SHM_FORMAT_XRGB8888:
gbm_format = GBM_FORMAT_XRGB8888;
break;
default:
g_warn_if_reached ();
gbm_format = GBM_FORMAT_ARGB8888;
}
load_scaled_and_transformed_cursor_sprite (native,
gpu_kms,
cursor_sprite,
relative_scale,
relative_transform,
buffer_data,
width,
height,
rowstride,
gbm_format);
wl_shm_buffer_end_access (shm_buffer);
}
else
{
MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
struct gbm_device *gbm_device;
struct gbm_bo *bo;
g_autoptr (GError) error = NULL;
MetaDrmBufferGbm *buffer_gbm;
/* HW cursors have a predefined size (at least 64x64), which usually is
* bigger than cursor theme size, so themed cursors must be padded with
* transparent pixels to fill the overlay. This is trivial if we have CPU
* access to the data, but it's not possible if the buffer is in GPU
* memory (and possibly tiled too), so if we don't get the right size, we
* fallback to GL. */
cursor_width = (uint64_t) cursor_renderer_gpu_data->cursor_width;
cursor_height = (uint64_t) cursor_renderer_gpu_data->cursor_height;
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture);
if (width != cursor_width || height != cursor_height)
{
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors");
return;
}
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
bo = gbm_bo_import (gbm_device,
GBM_BO_IMPORT_WL_BUFFER,
buffer,
GBM_BO_USE_CURSOR);
if (!bo)
{
meta_warning ("Importing HW cursor from wl_buffer failed");
return;
}
unset_can_preprocess (cursor_sprite);
buffer_gbm = meta_drm_buffer_gbm_new_take (kms_device, bo, FALSE, &error);
if (!buffer_gbm)
{
meta_warning ("Failed to create DRM buffer wrapper: %s",
error->message);
gbm_bo_destroy (bo);
return;
}
set_pending_cursor_sprite_buffer (cursor_sprite, gpu_kms,
META_DRM_BUFFER (buffer_gbm));
}
}
#endif
static void
realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer *renderer,
MetaGpuKms *gpu_kms,
MetaCursorSpriteXcursor *sprite_xcursor)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
XcursorImage *xc_image;
float relative_scale;
MetaMonitorTransform relative_transform;
ensure_cursor_priv (cursor_sprite);
cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
return;
if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms) &&
is_cursor_scale_and_transform_valid (renderer, cursor_sprite))
return;
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer,
cursor_sprite,
&relative_scale))
{
unset_can_preprocess (cursor_sprite);
return;
}
if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer,
cursor_sprite,
&relative_transform))
{
unset_can_preprocess (cursor_sprite);
return;
}
set_can_preprocess (cursor_sprite,
relative_scale,
relative_transform);
xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor);
load_scaled_and_transformed_cursor_sprite (native,
gpu_kms,
cursor_sprite,
relative_scale,
relative_transform,
(uint8_t *) xc_image->pixels,
xc_image->width,
xc_image->height,
xc_image->width * 4,
GBM_FORMAT_ARGB8888);
}
static void
realize_cursor_sprite_for_gpu (MetaCursorRenderer *renderer,
MetaGpuKms *gpu_kms,
MetaCursorSprite *cursor_sprite)
{
if (META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite))
{
MetaCursorSpriteXcursor *sprite_xcursor =
META_CURSOR_SPRITE_XCURSOR (cursor_sprite);
realize_cursor_sprite_from_xcursor_for_gpu (renderer,
gpu_kms,
sprite_xcursor);
}
#ifdef HAVE_WAYLAND
else if (META_IS_CURSOR_SPRITE_WAYLAND (cursor_sprite))
{
MetaCursorSpriteWayland *sprite_wayland =
META_CURSOR_SPRITE_WAYLAND (cursor_sprite);
realize_cursor_sprite_from_wl_buffer_for_gpu (renderer,
gpu_kms,
sprite_wayland);
}
#endif
}
static void
realize_cursor_sprite (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
GList *gpus)
{
GList *l;
for (l = gpus; l; l = l->next)
{
MetaGpuKms *gpu_kms = l->data;
realize_cursor_sprite_for_gpu (renderer, gpu_kms, cursor_sprite);
}
}
2014-04-22 19:15:11 +00:00
static void
meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
{
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_cursor_renderer_native_finalize;
renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor;
quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native");
quark_cursor_renderer_native_gpu_data =
g_quark_from_static_string ("-meta-cursor-renderer-native-gpu-data");
2014-04-22 19:15:11 +00:00
}
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
static void
force_update_hw_cursor (MetaCursorRendererNative *native)
{
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
priv->hw_state_invalidated = TRUE;
meta_cursor_renderer_force_update (renderer);
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
}
2014-04-22 19:15:11 +00:00
static void
on_monitors_changed (MetaMonitorManager *monitors,
MetaCursorRendererNative *native)
{
Support scaling of cursor sprites given what output they are on This commits refactors cursor handling code and plugs in logic so that cursor sprites changes appearance as it moves across the screen. Renderers are adapted to handle the necessary functionality. The logic for changing the cursor sprite appearance is done outside of MetaCursorSprite, and actually where depends on what type of cursor it is. In mutter we now have two types of cursors that may have their appearance changed: - Themed cursors (aka root cursors) - wl_surface cursors Themed cursors are created by MetaScreen and when created, when applicable(*), it will extend the cursor via connecting to a signal which is emitted everytime the cursor is moved. The signal handler will calculate the expected scale given the monitor it is on and reload the theme in a correct size when needed. wl_surface cursors are created when a wl_surface is assigned the "cursor" role, i.e. when a client calls wl_pointer.set_cursor. A cursor role object is created which is connected to the cursor object by the position signal, and will set a correct texture scale given what monitor the cursor is on and what scale the wl_surface's active buffer is in. It will also push new buffers to the same to the cursor object when new ones are committed to the surface. This commit also makes texture loading lazy, since the renderer doesn't calculate a rectangle when the cursor position changes. The native backend is refactored to be triple-buffered; see the comment in meta-cursor-renderer-native.c for further explanations. * when we are running as a Wayland compositor https://bugzilla.gnome.org/show_bug.cgi?id=744932
2015-07-17 15:16:39 +00:00
force_update_hw_cursor (native);
2014-04-22 19:15:11 +00:00
}
static void
init_hw_cursor_support_for_gpu (MetaGpuKms *gpu_kms)
{
MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
struct gbm_device *gbm_device;
uint64_t width, height;
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
if (!gbm_device)
return;
cursor_renderer_gpu_data =
meta_create_cursor_renderer_native_gpu_data (gpu_kms);
if (!meta_kms_device_get_cursor_size (kms_device, &width, &height))
{
width = 64;
height = 64;
}
cursor_renderer_gpu_data->cursor_width = width;
cursor_renderer_gpu_data->cursor_height = height;
}
static void
on_gpu_added_for_cursor (MetaBackend *backend,
MetaGpuKms *gpu_kms)
{
init_hw_cursor_support_for_gpu (gpu_kms);
}
2014-04-22 19:15:11 +00:00
static void
init_hw_cursor_support (MetaCursorRendererNative *cursor_renderer_native)
2014-04-22 19:15:11 +00:00
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
GList *gpus;
GList *l;
2014-04-22 19:15:11 +00:00
gpus = meta_backend_get_gpus (priv->backend);
for (l = gpus; l; l = l->next)
{
MetaGpuKms *gpu_kms = l->data;
init_hw_cursor_support_for_gpu (gpu_kms);
}
}
MetaCursorRendererNative *
meta_cursor_renderer_native_new (MetaBackend *backend,
ClutterInputDevice *device)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaCursorRendererNative *cursor_renderer_native;
MetaCursorRendererNativePrivate *priv;
cursor_renderer_native = g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE,
"backend", backend,
"device", device,
NULL);
priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
g_signal_connect_object (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed),
cursor_renderer_native, 0);
g_signal_connect (backend, "gpu-added",
G_CALLBACK (on_gpu_added_for_cursor), NULL);
priv->backend = backend;
priv->hw_state_invalidated = TRUE;
init_hw_cursor_support (cursor_renderer_native);
return cursor_renderer_native;
}
static void
meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
{
2014-04-22 19:15:11 +00:00
}