drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c
Extension
.c
Size
23263 bytes
Lines
859
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vmw_svga_fifo_cmd_define_cursor {
	u32 cmd;
	SVGAFifoCmdDefineAlphaCursor cursor;
};

/**
 * vmw_send_define_cursor_cmd - queue a define cursor command
 * @dev_priv: the private driver struct
 * @image: buffer which holds the cursor image
 * @width: width of the mouse cursor image
 * @height: height of the mouse cursor image
 * @hotspotX: the horizontal position of mouse hotspot
 * @hotspotY: the vertical position of mouse hotspot
 */
static void vmw_send_define_cursor_cmd(struct vmw_private *dev_priv,
				       u32 *image, u32 width, u32 height,
				       u32 hotspotX, u32 hotspotY)
{
	struct vmw_svga_fifo_cmd_define_cursor *cmd;
	const u32 image_size = width * height * sizeof(*image);
	const u32 cmd_size = sizeof(*cmd) + image_size;

	/*
	 * Try to reserve fifocmd space and swallow any failures;
	 * such reservations cannot be left unconsumed for long
	 * under the risk of clogging other fifocmd users, so
	 * we treat reservations separtely from the way we treat
	 * other fallible KMS-atomic resources at prepare_fb
	 */
	cmd = VMW_CMD_RESERVE(dev_priv, cmd_size);

	if (unlikely(!cmd))
		return;

	memset(cmd, 0, sizeof(*cmd));

	memcpy(&cmd[1], image, image_size);

	cmd->cmd = SVGA_CMD_DEFINE_ALPHA_CURSOR;
	cmd->cursor.id = 0;
	cmd->cursor.width = width;
	cmd->cursor.height = height;
	cmd->cursor.hotspotX = hotspotX;
	cmd->cursor.hotspotY = hotspotY;

	vmw_cmd_commit_flush(dev_priv, cmd_size);
}

static void
vmw_cursor_plane_update_legacy(struct vmw_private *vmw,
			       struct vmw_plane_state *vps)
{
	struct vmw_surface *surface = vmw_user_object_surface(&vps->uo);
	s32 hotspot_x = vps->cursor.legacy.hotspot_x + vps->base.hotspot_x;
	s32 hotspot_y = vps->cursor.legacy.hotspot_y + vps->base.hotspot_y;

	if (WARN_ON(!surface || !surface->snooper.image))
		return;

	if (vps->cursor.legacy.id != surface->snooper.id) {
		vmw_send_define_cursor_cmd(vmw, surface->snooper.image,
					   vps->base.crtc_w, vps->base.crtc_h,
					   hotspot_x, hotspot_y);
		vps->cursor.legacy.id = surface->snooper.id;
	}
}

static enum vmw_cursor_update_type
vmw_cursor_update_type(struct vmw_private *vmw, struct vmw_plane_state *vps)
{
	struct vmw_surface *surface = vmw_user_object_surface(&vps->uo);

	if (surface && surface->snooper.image)
		return VMW_CURSOR_UPDATE_LEGACY;

	if (vmw->has_mob) {
		if ((vmw->capabilities2 & SVGA_CAP2_CURSOR_MOB) != 0)
			return VMW_CURSOR_UPDATE_MOB;
		else
			return VMW_CURSOR_UPDATE_GB_ONLY;
	}
	drm_warn_once(&vmw->drm, "Unknown Cursor Type!\n");
	return VMW_CURSOR_UPDATE_NONE;
}

static void vmw_cursor_update_mob(struct vmw_private *vmw,
				  struct vmw_plane_state *vps)
{
	SVGAGBCursorHeader *header;
	SVGAGBAlphaCursorHeader *alpha_header;

Annotation

Implementation Notes