Changeset 64919 in vbox for trunk/src/VBox/Additions/linux
- Timestamp:
- Dec 16, 2016 4:56:09 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 112332
- Location:
- trunk/src/VBox/Additions/linux/drm
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/drm/README.testing
r63772 r64919 1 This document lists things which have been known to fail in the past with the drm video driver and which should be tested regularly, e.g. when making code changes or before releases. 1 This document lists things which have been known to fail in the past with the 2 drm video driver and which should be tested regularly, e.g. when making code 3 changes or before releases. 2 4 3 5 * Test that "auto-resize" is enabled in the GUI if user space supports it. 4 * Test that old versions of Plymouth which do not report rectangles (pre-0.9.0/2014-05-20) update the screen correctly. 6 * Test that old versions of Plymouth which do not report rectangles 7 (pre-0.9.0/2014-05-20) update the screen correctly. 8 * Having valid, non-overlapping offset hints on all screens has caused 9 mouse integration and/or screen updates to break for fbdev, X.Org or 10 GNOME Shell/Wayland. 11 * Note that if a multi-screen VM is booted with only one screen enabled 12 the fbdev console will be disabled on the others until reboot. Test this 13 configuration. -
trunk/src/VBox/Additions/linux/drm/vbox_drv.h
r64830 r64919 97 97 bool any_pitch; 98 98 unsigned num_crtcs; 99 bool vga2_clone;100 99 /** Amount of available VRAM, including space used for buffers. */ 101 100 uint32_t full_vram_size; … … 129 128 uint32_t input_mapping_width; 130 129 uint32_t input_mapping_height; 130 /** Is user-space using an X.Org-style layout of one large frame-buffer 131 * encompassing all screen ones or is the fbdev console active? */ 132 bool single_framebuffer; 131 133 uint32_t cursor_width; 132 134 uint32_t cursor_height; … … 169 171 uint32_t fb_offset; 170 172 bool cursor_enabled; 173 uint16_t x_hint; 174 uint16_t y_hint; 171 175 }; 172 176 -
trunk/src/VBox/Additions/linux/drm/vbox_irq.c
r64425 r64919 85 85 } 86 86 87 /** Check that the position hints provided by the host are suitable for GNOME 88 * shell (i.e. all screens disjoint and hints for all enabled screens) and if 89 * not replace them with default ones. Providing valid hints improves the 90 * chances that we will get a known screen layout for pointer mapping. */ 91 static void validate_or_set_position_hints(struct vbox_private *vbox) 92 { 93 int i, j; 94 uint16_t currentx = 0; 95 bool valid = true; 96 97 for (i = 0; i < vbox->num_crtcs; ++i) { 98 for (j = 0; j < i; ++j) { 99 struct VBVAMODEHINT *hintsi = &vbox->last_mode_hints[i]; 100 struct VBVAMODEHINT *hintsj = &vbox->last_mode_hints[j]; 101 102 if (hintsi->fEnabled && hintsj->fEnabled) { 103 if ((hintsi->dx >= 0xffff || hintsi->dy >= 0xffff || 104 hintsj->dx >= 0xffff || hintsj->dy >= 0xffff) || 105 (hintsi->dx < hintsj->dx + (hintsj->cx & 0x8fff) && 106 hintsi->dx + (hintsi->cx & 0x8fff) > hintsj->dx) || 107 (hintsi->dy < hintsj->dy + (hintsj->cy & 0x8fff) && 108 hintsi->dy + (hintsi->cy & 0x8fff) > hintsj->dy)) 109 valid = false; 110 } 111 } 112 } 113 if (!valid) 114 for (i = 0; i < vbox->num_crtcs; ++i) { 115 if (vbox->last_mode_hints[i].fEnabled) { 116 vbox->last_mode_hints[i].dx = currentx; 117 vbox->last_mode_hints[i].dy = 0; 118 currentx += vbox->last_mode_hints[i].cx & 0x8fff; 119 } 120 } 121 } 122 87 123 /** 88 * Query the host for 124 * Query the host for the most recent video mode hints. 89 125 */ 90 126 static void vbox_update_mode_hints(struct vbox_private *vbox) … … 105 141 return; 106 142 } 143 validate_or_set_position_hints(vbox); 107 144 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) 108 145 drm_modeset_lock_all(dev); … … 120 157 vbox_connector->mode_hint.width = hints->cx & 0x8fff; 121 158 vbox_connector->mode_hint.height = hints->cy & 0x8fff; 159 vbox_connector->vbox_crtc->x_hint = hints->dx; 160 vbox_connector->vbox_crtc->y_hint = hints->dy; 122 161 vbox_connector->mode_hint.disconnected = disconnected; 123 162 if (vbox_connector->vbox_crtc->disconnected != disconnected) { … … 127 166 vbox_connector->vbox_crtc->disconnected = disconnected; 128 167 } 129 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)130 if ((hints->dx < 0xffff) && (hints->dy < 0xffff)) {131 drm_object_property_set_value(&connector->base,132 dev->mode_config.suggested_x_property, hints->dx & 0x8fff);133 drm_object_property_set_value(&connector->base,134 dev->mode_config.suggested_y_property, hints->dy & 0x8fff);135 }136 #endif137 168 } 138 169 } -
trunk/src/VBox/Additions/linux/drm/vbox_mode.c
r64830 r64919 74 74 unsigned crtc_id; 75 75 uint16_t flags; 76 int32_t x_offset, y_offset; 76 77 77 78 vbox = crtc->dev->dev_private; … … 85 86 pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8; 86 87 #endif 88 x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint; 89 y_offset = vbox->single_framebuffer ? crtc->y : vbox_crtc->y_hint; 87 90 /* This is the old way of setting graphics modes. It assumed one screen 88 91 * and a frame-buffer at the start of video RAM. On older versions of … … 101 104 flags |= (vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0); 102 105 VBoxHGSMIProcessDisplayInfo(&vbox->submit_info, vbox_crtc->crtc_id, 103 crtc->x, crtc->y,106 x_offset, y_offset, 104 107 crtc->x * bpp / 8 + crtc->y * pitch, 105 108 pitch, width, height, … … 171 174 } 172 175 176 /* Try to map the layout of virtual screens to the range of the input device. 177 * Return true if we need to re-set the crtc modes due to screen offset 178 * changes. */ 179 static bool vbox_set_up_input_mapping(struct vbox_private *vbox) 180 { 181 struct drm_crtc *crtci; 182 struct drm_connector *connectori; 183 struct drm_framebuffer *fb1 = NULL; 184 bool single_framebuffer = true; 185 bool old_single_framebuffer = vbox->single_framebuffer; 186 uint16_t width = 0, height = 0; 187 188 /* Are we using an X.Org-style single large frame-buffer for all crtcs? 189 * If so then screen layout can be deduced from the crtc offsets. 190 * Same fall-back if this is the fbdev frame-buffer. */ 191 list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) { 192 if (fb1 == NULL) { 193 fb1 = CRTC_FB(crtci); 194 if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb) 195 break; 196 } else if (CRTC_FB(crtci) != NULL && fb1 != CRTC_FB(crtci)) 197 single_framebuffer = false; 198 } 199 if (single_framebuffer) { 200 list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) { 201 if (to_vbox_crtc(crtci)->crtc_id == 0) { 202 vbox->single_framebuffer = true; 203 vbox->input_mapping_width = CRTC_FB(crtci)->width; 204 vbox->input_mapping_height = CRTC_FB(crtci)->height; 205 return old_single_framebuffer != vbox->single_framebuffer; 206 } 207 } 208 } 209 /* Otherwise calculate the total span of all screens. */ 210 list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list, 211 head) { 212 struct vbox_connector *vbox_connector = to_vbox_connector(connectori); 213 struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc; 214 215 width = max(width, (uint16_t) (vbox_crtc->x_hint + 216 vbox_connector->mode_hint.width)); 217 height = max(height, (uint16_t) (vbox_crtc->y_hint + 218 vbox_connector->mode_hint.height)); 219 } 220 vbox->single_framebuffer = false; 221 vbox->input_mapping_width = width; 222 vbox->input_mapping_height = height; 223 return old_single_framebuffer != vbox->single_framebuffer; 224 } 225 173 226 static int vbox_crtc_do_set_base(struct drm_crtc *crtc, 174 227 struct drm_framebuffer *old_fb, … … 215 268 /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */ 216 269 vbox_crtc->fb_offset = gpu_addr; 217 if (vbox_crtc->crtc_id == 0) { 218 vbox->input_mapping_width = CRTC_FB(crtc)->width; 219 vbox->input_mapping_height = CRTC_FB(crtc)->height; 270 if (vbox_set_up_input_mapping(vbox)) { 271 struct drm_crtc *crtci; 272 273 list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) { 274 vbox_set_view(crtc); 275 vbox_do_modeset(crtci, &crtci->mode); 276 } 220 277 } 221 278 return 0; … … 242 299 if (!rc) 243 300 vbox_do_modeset(crtc, mode); 244 /* Note that the input mapping is always relative to the first screen. */245 301 VBoxHGSMIUpdateInputMapping(&vbox->submit_info, 0, 0, 246 302 vbox->input_mapping_width, … … 505 561 } 506 562 vbox_set_edid(connector, preferred_width, preferred_height); 563 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) 564 drm_object_property_set_value(&connector->base, 565 vbox->dev->mode_config.suggested_x_property, 566 vbox_connector->vbox_crtc->x_hint); 567 drm_object_property_set_value(&connector->base, 568 vbox->dev->mode_config.suggested_y_property, 569 vbox_connector->vbox_crtc->y_hint); 570 #endif 507 571 return num_modes; 508 572 } … … 592 656 drm_mode_create_suggested_offset_properties(dev); 593 657 drm_object_attach_property(&connector->base, 594 dev->mode_config.suggested_x_property, 0);658 dev->mode_config.suggested_x_property, -1); 595 659 drm_object_attach_property(&connector->base, 596 dev->mode_config.suggested_y_property, 0);660 dev->mode_config.suggested_y_property, -1); 597 661 #endif 598 662 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) … … 763 827 | VBOX_MOUSE_POINTER_SHAPE 764 828 | VBOX_MOUSE_POINTER_ALPHA; 829 int32_t crtc_x = vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint; 830 int32_t crtc_y = vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint; 765 831 uint32_t host_x, host_y; 766 832 uint32_t hot_x = 0; … … 769 835 770 836 /* We compare these to unsigned later and don't need to handle negative. */ 771 if (x + crtc ->x < 0 || y + crtc->y < 0 || vbox->cursor_data_size == 0)837 if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0) 772 838 return 0; 773 rc = VBoxHGSMICursorPosition(&vbox->submit_info, true, x + crtc ->x,774 y + crtc ->y, &host_x, &host_y);839 rc = VBoxHGSMICursorPosition(&vbox->submit_info, true, x + crtc_x, 840 y + crtc_y, &host_x, &host_y); 775 841 /* Work around a bug after save and restore in 5.0.20 and earlier. */ 776 842 if (RT_FAILURE(rc) || (host_x == 0 && host_y == 0)) … … 778 844 : rc == VERR_NO_MEMORY ? -ENOMEM 779 845 : -EINVAL; 780 if (x + crtc ->x < host_x)781 hot_x = min(host_x - x - crtc ->x, vbox->cursor_width);782 if (y + crtc ->y < host_y)783 hot_y = min(host_y - y - crtc ->y, vbox->cursor_height);846 if (x + crtc_x < host_x) 847 hot_x = min(host_x - x - crtc_x, vbox->cursor_width); 848 if (y + crtc_y < host_y) 849 hot_y = min(host_y - y - crtc_y, vbox->cursor_height); 784 850 if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y) 785 851 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.