// SPDX-License-Identifier: MIT /* * Copyright (C) 2013-2017 Oracle Corporation * This file is based on ast_mode.c * Copyright 2012 Red Hat Inc. * Parts based on xf86-video-ast * Copyright (c) 2005 ASPEED Technology Inc. * Authors: Dave Airlie <airlied@redhat.com> * Michael Thayer <michael.thayer@oracle.com, * Hans de Goede <hdegoede@redhat.com>
*/
/* * Set a graphics mode. Poke any required values into registers, do an HGSMI * mode set and tell the host we support advanced graphics functions.
*/ staticvoid vbox_do_modeset(struct drm_crtc *crtc)
{ struct drm_framebuffer *fb = crtc->primary->state->fb; struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); struct vbox_private *vbox; int width, height, bpp, pitch;
u16 flags;
s32 x_offset, y_offset;
/* * This is the old way of setting graphics modes. It assumed one screen * and a frame-buffer at the start of video RAM. On older versions of * VirtualBox, certain parts of the code still assume that the first * screen is programmed this way, so try to fake it.
*/ if (vbox_crtc->crtc_id == 0 && fb &&
vbox_crtc->fb_offset / pitch < 0xffff - crtc->y &&
vbox_crtc->fb_offset % (bpp / 8) == 0) {
vbox_write_ioport(VBE_DISPI_INDEX_XRES, width);
vbox_write_ioport(VBE_DISPI_INDEX_YRES, height);
vbox_write_ioport(VBE_DISPI_INDEX_VIRT_WIDTH, pitch * 8 / bpp);
vbox_write_ioport(VBE_DISPI_INDEX_BPP, bpp);
vbox_write_ioport(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
vbox_write_ioport(VBE_DISPI_INDEX_X_OFFSET,
vbox_crtc->fb_offset % pitch / bpp * 8 + vbox_crtc->x);
vbox_write_ioport(VBE_DISPI_INDEX_Y_OFFSET,
vbox_crtc->fb_offset / pitch + vbox_crtc->y);
}
/* * Tell the host about the view. This design originally targeted the * Windows XP driver architecture and assumed that each screen would * have a dedicated frame buffer with the command buffer following it, * the whole being a "view". The host works out which screen a command * buffer belongs to by checking whether it is in the first view, then * whether it is in the second and so on. The first match wins. We * cheat around this by making the first view be the managed memory * plus the first command buffer, the second the same plus the second * buffer and so on.
*/
p = hgsmi_buffer_alloc(vbox->guest_pool, sizeof(*p),
HGSMI_CH_VBVA, VBVA_INFO_VIEW); if (!p) return -ENOMEM;
/* * Try to map the layout of virtual screens to the range of the input device. * Return true if we need to re-set the crtc modes due to screen offset * changes.
*/ staticbool vbox_set_up_input_mapping(struct vbox_private *vbox)
{ struct drm_crtc *crtci; struct drm_connector *connectori; struct drm_framebuffer *fb, *fb1 = NULL; bool single_framebuffer = true; bool old_single_framebuffer = vbox->single_framebuffer;
u16 width = 0, height = 0;
/* * Are we using an X.Org-style single large frame-buffer for all crtcs? * If so then screen layout can be deduced from the crtc offsets. * Same fall-back if this is the fbdev frame-buffer.
*/
list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) {
fb = crtci->primary->state->fb; if (!fb) continue;
if (!fb1) {
fb1 = fb; if (fb1 == vbox->ddev.fb_helper->fb) break;
} elseif (fb != fb1) {
single_framebuffer = false;
}
} if (!fb1) returnfalse;
if (single_framebuffer) {
vbox->single_framebuffer = true;
vbox->input_mapping_width = fb1->width;
vbox->input_mapping_height = fb1->height; return old_single_framebuffer != vbox->single_framebuffer;
} /* Otherwise calculate the total span of all screens. */
list_for_each_entry(connectori, &vbox->ddev.mode_config.connector_list,
head) { struct vbox_connector *vbox_connector =
to_vbox_connector(connectori); struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc;
/* vbox_do_modeset() checks vbox->single_framebuffer so update it now */ if (needs_modeset && vbox_set_up_input_mapping(vbox)) { struct drm_crtc *crtci;
/* * Copy the ARGB image and generate the mask, which is needed in case the host * does not support ARGB cursors. The mask is a 1BPP bitmap with the bit set * if the corresponding alpha value in the ARGB image is greater than 0xF0.
*/ staticvoid copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
size_t mask_size)
{
size_t line_size = (width + 7) / 8;
u32 i, j;
memcpy(dst + mask_size, src, width * height * 4); for (i = 0; i < height; ++i) for (j = 0; j < width; ++j) if (((u32 *)src)[i * width + j] > 0xf0000000)
dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
}
/* * VirtualBox uses the host windowing system to draw the cursor so * moves are a no-op, we only need to upload new cursor sprites.
*/ if (fb == old_state->fb) return;
mutex_lock(&vbox->hw_mutex);
vbox_crtc->cursor_enabled = true;
/* * The mask must be calculated based on the alpha * channel, one bit per ARGB word, and must be 32-bit * padded.
*/
mask_size = ((width + 7) / 8 * height + 3) & ~3;
data_size = width * height * 4 + mask_size;
ret = hgsmi_query_conf(vbox->guest_pool,
VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps); if (ret) return ERR_PTR(ret);
vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL); if (!vbox_crtc) return ERR_PTR(-ENOMEM);
primary = vbox_create_plane(vbox, 1 << i, DRM_PLANE_TYPE_PRIMARY); if (IS_ERR(primary)) {
ret = PTR_ERR(primary); goto free_mem;
}
if ((caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
cursor = vbox_create_plane(vbox, 1 << i, DRM_PLANE_TYPE_CURSOR); if (IS_ERR(cursor)) {
ret = PTR_ERR(cursor); goto clean_primary;
}
} else {
DRM_WARN("VirtualBox host is too old, no cursor support\n");
}
vbox_crtc->crtc_id = i;
ret = drm_crtc_init_with_planes(dev, &vbox_crtc->base, primary, cursor,
&vbox_crtc_funcs, NULL); if (ret) goto clean_cursor;
for (i = 0; i < vbox->num_crtcs; ++i) {
vbox_crtc = vbox_crtc_init(dev, i); if (IS_ERR(vbox_crtc)) {
ret = PTR_ERR(vbox_crtc); goto err_drm_mode_cleanup;
}
encoder = vbox_encoder_init(dev, i); if (!encoder) {
ret = -ENOMEM; goto err_drm_mode_cleanup;
}
ret = vbox_connector_init(dev, vbox_crtc, encoder); if (ret) goto err_drm_mode_cleanup;
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.14Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-04-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.