0001-SNA-fix-PRIME-output-support-since-xserver-1.20.patch 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. From e85424325911626556fbe5a313c698a5da701163 Mon Sep 17 00:00:00 2001
  2. From: Peter Wu <peter@lekensteyn.nl>
  3. Date: Mon, 13 Aug 2018 22:59:50 +0200
  4. Subject: [PATCH xf86-video-intel] SNA: fix PRIME output support since xserver
  5. 1.20
  6. Since xorg-server 1.20, an external monitor would remain blank when used
  7. in a PRIME output slave setup. Only a cursor was visible. The cause is
  8. "Make PixmapDirtyUpdateRec::src a DrawablePtr" in xserver, the "src"
  9. pointer might point to the root window (created by the server) instead
  10. of a pixmap (as created by xf86-video-intel). Use get_drawable_pixmap to
  11. handle both cases.
  12. When built with -fsanitize=address, the following test will trigger a
  13. heap-buffer-overflow error due to to_sna_from_pixmap receiving a window
  14. instead of a pixmap.
  15. Test on a hybrid graphics laptop (Intel + modesetting/nouveau):
  16. xrandr --setprovideroutputsource modesetting Intel
  17. xrandr --output DP-1-1 --mode 2560x1440 # should not crash
  18. glxgears # should display gears on both screens
  19. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100086
  20. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
  21. ---
  22. Tested with xserver 1.20.1 with ASAN enabled. Survives multiple
  23. resolution changes, works with a Plasma desktop session, it seems
  24. stable. Something like this patch is required to make multi-monitor
  25. setups usable in a hybrid graphics setting with Xorg 1.20.
  26. ---
  27. src/sna/sna_accel.c | 18 ++++++++++++++++++
  28. 1 file changed, 18 insertions(+)
  29. diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
  30. index 2f669bcf..80b116a3 100644
  31. --- a/src/sna/sna_accel.c
  32. +++ b/src/sna/sna_accel.c
  33. @@ -17510,7 +17510,11 @@ static bool has_offload_slaves(struct sna *sna)
  34. PixmapDirtyUpdatePtr dirty;
  35. xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
  36. +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
  37. + assert(dirty->src == &sna->front->drawable);
  38. +#else
  39. assert(dirty->src == sna->front);
  40. +#endif
  41. if (RegionNotEmpty(DamageRegion(dirty->damage)))
  42. return true;
  43. }
  44. @@ -17671,7 +17675,11 @@ static void sna_accel_post_damage(struct sna *sna)
  45. if (RegionNil(damage))
  46. continue;
  47. +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
  48. + src = get_drawable_pixmap(dirty->src);
  49. +#else
  50. src = dirty->src;
  51. +#endif
  52. dst = dirty->slave_dst->master_pixmap;
  53. region.extents.x1 = dirty->x;
  54. @@ -17922,9 +17930,15 @@ migrate_dirty_tracking(PixmapPtr old_front, PixmapPtr new_front)
  55. PixmapDirtyUpdatePtr dirty, safe;
  56. xorg_list_for_each_entry_safe(dirty, safe, &screen->pixmap_dirty_list, ent) {
  57. +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
  58. + assert(dirty->src == &old_front->drawable);
  59. + if (dirty->src != &old_front->drawable)
  60. + continue;
  61. +#else
  62. assert(dirty->src == old_front);
  63. if (dirty->src != old_front)
  64. continue;
  65. +#endif
  66. DamageUnregister(&dirty->src->drawable, dirty->damage);
  67. DamageDestroy(dirty->damage);
  68. @@ -17939,7 +17953,11 @@ migrate_dirty_tracking(PixmapPtr old_front, PixmapPtr new_front)
  69. }
  70. DamageRegister(&new_front->drawable, dirty->damage);
  71. +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
  72. + dirty->src = &new_front->drawable;
  73. +#else
  74. dirty->src = new_front;
  75. +#endif
  76. }
  77. #endif
  78. }
  79. --
  80. 2.18.0