Commit Graph

4272 Commits

Author SHA1 Message Date
Keith Packard
69b782aa75 xfree86: Set pScrn->pScreen before driver ScreenInit is called
Any code called from the driver ScreenInit may want to refer to
pScrn->pScreen. As the function passed to AddScreen is the first place
the DDX sees a new screen, the generic code needs to make sure that
value is set before passing control to the video driver's
initialization code.

This was found by running a driver which didn't bother to set this
value when the initial colormap was installed; xf86RandR12LoadPalette
tried to use pScrn->pScreen and crashed.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97124
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer@amd.com>
2016-08-13 09:18:15 -07:00
Peter Hutterer
f399919e13 xfree86: lock input during PreInit
This is a problem for the libinput driver that uses the same context across
multiple devices. The driver may be halfway through setting up an input device
(and the only way to do so is to add it to libinput) when the input thread
comes in an reads events. This then causes mayhem when data is dereferenced
that hasn't been set up yet.

In my case the cause was the call to libinput_path_remove_device() inside
preinit racing with evdev_dispatch_device() handling of ENODEV. The sequence
was:
- thread 2 gets an event and calls evdev_dispatch_device()
- thread 1 calls libinput_path_remove_device() which sets the device->source
  to NULL
- thread 2 reads from the fd, gets ENODEV and now removes the device->source,
  dereferencing the null-pointer

This is the one I could reproduce the most, but there are other potential
pitfalls that affect any driver that uses the same fd for multiple devices.
Avoid all this and wrap PreInit into the lock.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
2016-08-12 14:43:08 +10:00
Peter Hutterer
dd4e21cb3a xfree86: fix unbalanced input_lock/unlock in xf86NewInputDevice()
If a device couldn't be enabled we left the lock hanging.

This patch also removes the leftover OsReleaseSignals() call, now unnecessary.
Note that input_unlock() is later than previously OsReleaseSignals().
RemoveDevice() manipulates the input device and its file descriptors, it's
safer to put the input_unlock() call after RemoveDevice() to avoid events
coming in while the device is being removed.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
2016-08-12 14:41:19 +10:00
Michel Dänzer
a446ff84de xfree86/modes: Handle no palette case better in xf86RandR12CrtcSetGamma
Just use the RandR gamma ramp directly.

Fixes random on-monitor colours with drivers which don't call
xf86HandleColormaps, e.g. modesetting.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97154

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
2016-08-10 16:56:09 +09:00
Kenneth Graunke
d3d4ff0ed4 modesetting: Delete dead drmmode_bo_for_pixmap function.
Embarassingly, it looks like I introduced this dead function in
commit 13c7d53df8 a year ago.
Nothing ever used it, not even then.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
2016-08-08 23:42:40 -07:00
Michel Dänzer
b4e46c0444 xfree86: Hook up colormaps and RandR 1.2 gamma code v6
Instead of breaking the former when the driver supports the latter,
hook them up so that the hardware LUTs reflect the combination of the
current colourmap and gamma states. I.e. combine the colourmap, the
global gamma value/ramp and the RandR 1.2 per-CRTC gamma ramps into one
combined LUT per CRTC.

Fixes e.g. gamma sliders not working in games.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27222

v2:
* Initialize palette_size and palette struct members, fixes crash on
  server startup.
v3:
* Free randrp->palette in xf86RandR12CloseScreen, fixes memory leak.
v4:
* Call CMapUnwrapScreen if xf86RandR12InitGamma fails (Emil Velikov).
* Still allow xf86HandleColormaps to be called with a NULL loadPalette
  parameter in the xf86_crtc_supports_gamma case.
v5:
* Clean up inner loops in xf86RandR12CrtcComputeGamma (Keith Packard)
* Move palette update out of per-CRTC loop in xf86RandR12LoadPalette
  (Keith Packard)
v6:
* Handle reallocarray failure in xf86RandR12LoadPalette (Keith Packard)

Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-28 10:12:05 +09:00
Michel Dänzer
17213b74fd xfree86/modes: Remove xf86RandR12CrtcGetGamma
This would normally return the same values the core RandR code passed to
xf86RandR12CrtcSetGamma before, which is rather pointless. The only
possible exception would be if a driver tried initializing
crtc->gamma_red/green/blue to reflect the hardware LUT state on startup,
but that can't work correctly if whatever set the LUT before the server
started was running at a different depth.

Even the pointless round-trip case will no longer work with the
following change.

Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-28 10:11:14 +09:00
Michel Dänzer
62f4405257 xfree86/modes: Move gamma initialization to xf86RandR12Init12 v2
RRCrtcGammaSetSize cannot be used yet in xf86InitialConfiguration,
because randr_crtc isn't allocated yet at that point, but a following
change will require RRCrtcGammaSetSize to be called from
xf86RandR12CrtcInitGamma.

v2:
* Bail from xf86RandR12CrtcInitGamma if !crtc->funcs->gamma_set (Keith
  Packard)

Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-27 17:49:39 +09:00
Keith Packard
d403aca70a Switch poll() users to xserver_poll()
This uses the wrapper in case we need to emulate poll with select
as we do on Windows.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
2016-07-21 15:04:36 -04:00
Peter Hutterer
7f2d690725 xfree86: if ATTR_KEYBOARD is set, match for keyboards
ATTR_KEY maps to ID_INPUT_KEY which is set for any device with keys.
ID_INPUT_KEYBOARD and thus ATTR_KEYBOARD is set for devices that are actual
keyboards (and have a set of expected keys).

Hand-written match rules may only apply ID_INPUT_KEYBOARD, so make sure we
match on that too.

Arguably we should've been matching on ATTR_KEYBOARD only all along but
changing that likely introduces regressions.

Reported-by: Marty Plummer <netz.kernel@gmail.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-07-18 16:40:46 -04:00
Adam Jackson
4b311d23e8 modesetting: resubmit dirty rects on EINVAL (v2)
This error code can mean we're submitting more rects at once than the
driver can handle. If that happens, resubmit one at a time.

v2: Make the rect submit loop more error-proof (Walter Harms)

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Michael Thayer <michael.thayer@oracle.com>
2016-07-18 16:35:16 -04:00
Keith Packard
4af00242ef Bump ABI versions to reflect block/wakeup handler API changes
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:27:51 -04:00
Keith Packard
9d15912aa4 Remove fd_set from Block/Wakeup handler API
This removes the last uses of fd_set from the server interfaces
outside of the OS layer itself.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:27:51 -04:00
Keith Packard
fb0802113b Remove readmask from screen block/wakeup handler
With no users of the interface needing the readmask anymore, we can
remove it from the argument passed to these functions.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:27:51 -04:00
Keith Packard
6299ef3d74 modesetting: Use passed-in fd for drm event monitoring NotifyFd callback
This is a cleanup, proposed by Adam Jackson, but wasn't merged with
the original NotifyFD changes.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
24e65bf0db hw/xfree86: Use NotifyFd for other input fd wakeups
Remove code in xf86Wakeup for dealing with other input and switch to
using the new NotifyFd interface.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
aa6717ce21 xfree86: Switch from select(2) to poll(2)
xf86WaitForInput and the xf86 SIGIO handling code.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
05a793f5b3 dix: Switch to the libXfont2 API (v2)
This new libXfont API eliminates exposing internal X server symbols to
the font library, replacing those with a struct full of the entire API
needed to use that library.

v2: Use libXfont2 instead of libXfont_2

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Adam Jackson
32a9504c69 xfree86: Fix fallback driver sort order for Xorg -configure (v2)
The intent here was that fallback drivers would be at the end of the
list in order, but if a fallback driver happened to be at the end of the
list already that's not what would happen. Rather than open-code
something smarter, just use qsort.

Note that qsort puts things in ascending order, so somewhat backwardsly
fallbacks are greater than native drivers, and vesa is greater than
modesetting.

v2: Use strcmp to compare non-fallback drivers so we get a predictable
result if your libc's qsort isn't stable (Keith Packard)

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
2016-07-15 11:08:01 -04:00
Hans De Goede
033888e776 linux: Do not try to open /dev/vc/0, fix error msg when /dev/tty0 open fails
/dev/vc/0 is a devfs thing which is long dead, so stop trying to open
/dev/vc/0, besides being a (small) code cleanup this will also fix the
"parse_vt_settings: Cannot open /dev/tty0 (%s)\n" error message to
display the actual error, rather then the -ENOENT from also trying
/dev/vc/0.

BugLink: https://patchwork.freedesktop.org/patch/8768/
Reported-by: Chad Versace <chad.versace@linux.intel.com>
Suggested-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
Reviewed-by: Chad Versace <chad.versace@intel.com>
2016-07-08 13:43:25 -04:00
Alex Goins
ce24f3aa58 modesetting: NULL assignment for drmmode_set_target_scanout_target_cpu
Commit 80e64dae: "modesetting: Implement PRIME syncing as a sink" originally was
supposed to have this line, but it was dropped as part of the merge process.

Foregoing the NULL assignment causes a ton of problems with dereferencing
uninitialized memory.

Signed-off-by: Alex Goins <agoins@nvidia.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-07-08 13:40:15 -04:00
Hans de Goede
60ad701a6a modesetting: Load on GPU-s with 0 outputs
In newer laptops with switchable graphics, the GPU may have 0 outputs,
in this case the modesetting driver should still load if the GPU is
SourceOffload capable, so that it can be used as an offload source provider.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
2016-07-02 09:54:07 +02:00
Hans de Goede
94a1c77259 modesetting: Fix swapping of provider sink / source capabilities
When a card has import capability it can be an offload _sink_, not
a source and vice versa for export capability.

This commit fixes the modesetting driver to properly set these
capabilities, this went unnoticed sofar because most gpus have both
import and export capability.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
2016-07-02 09:54:07 +02:00
Adam Jackson
fcbafdfd79 modesetting: Implement a double-buffered shadow mode
Server GPUs often have a VNC feature attached to allow remote console.
The controller implementing this feature is usually not very powerful,
and we can easily swamp it with work.  This is made somewhat worse by
damage over-reporting the size of the dirty region, and a whole lot
worse by applications (or shells) that update the screen with identical
pixel content as was already there.

Fix this by double-buffering the shadow fb, using memcmp to identify
dirty tiles on each update pass.  Since both shadows are in host memory
the memcmp is cheap, and worth it given the win in network bandwidth.
The tile size is somewhat arbitrarily chosen to be one cacheline wide at
32bpp on Intel Core.

By default we enable this behaviour for (a subset of) known server GPUs;
the heuristic could use work.

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-02 09:54:07 +02:00
Adam Jackson
75e660e379 modesetting: Drop some non-functional triple-buffering variables
Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-02 09:28:04 +02:00
Dave Airlie
21217d0216 modesetting: Implement 32->24 bpp conversion in shadow update
24bpp front buffers tend to be the least well tested path for client
rendering.  On the qemu cirrus emulation, and on some Matrox G200 server
chips, the hardware can't do 32bpp at all.  It's better to just allocate
a 32bpp shadow and downconvert in the upload hook than expose a funky
pixmap format to clients.

[ajax: Ported from RHEL and separate modesetting driver, lifted kbpp
into the drmmode struct, cleaned up commit message, fixed 16bpp]

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Dave Airlied <airlied@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
[hdegoede@redhat.com: rebase, also use kbpp for rotate shadow fb]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-02 09:28:04 +02:00
Takashi Iwai
af916477c6 modesetting: Fix hw cursor check at the first call
With the previous patch, the modesetting driver can now return whether
the driver supports hw cursor.  However, it alone doesn't suffice,
unfortunately. drmmode_load_cursor_argb_check() is called in the
following chain:

  xf86CursorSetCursor()
    -> xf86SetCursor()
       -> xf86DriverLoadCursorARGB()
         -> xf86_load_cursor_argb()
           -> xf86_crtc_load_cursor_argb()
             -> drmmode_load_cursor_argb_check()

*but* at first with drmmode_crtc->cursor_up = FALSE.  Then the
function doesn't actually set the cursor but returns TRUE
unconditionally.  The actual call of drmmode_set_cursor() is done at
first via the show_cursor callback, and there is no check of sw cursor
fallback any longer at this place. Since it's called only once per
cursor setup, so the xserver still thinks as if the hw cursor is
supported.

This patch is an ad hoc fix to correct the behavior somehow: it does
call drmmode_set_cursor() at the very first time even if cursor_up is
FALSE, then quickly hides again.  In that way, whether the hw cursor
is supported is evaluated in the right place at the right time.

Of course, it might be more elegant if we have a more proper mechanism
to fall back to sw cursor at any call path.  But it'd need more
rework, so I leave this workaround as is for now.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-02 09:26:11 +02:00
Takashi Iwai
14c21ea1c9 modesetting: Use load_cursor_argb_check for sw cursor fallback
The modesetting driver still has an everlasting bug of invisible
cursor on cirrus and other KMS drivers where no hardware cursor is
supported.  This patch is a part of an attempt to address it.

This patch particularly converts the current load_cursor_argb callback
of modesetting driver to load_cursor_argb_check so that it can return
whether the driver handles the hw cursor or falls back to the sw
cursor.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
[hdegoede@redhat.com: Add extra comment suggested by Kenneth]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-01 19:08:20 +02:00
Takashi Iwai
074cf58769 modesetting: Fix the error check from DRM_IOCTL_MODE_CURSOR2
The error value isn't always -EINVAL, e.g. the kernel drm core returns
-ENXIO when the corresponding ops doesn't exist.  Without this fix,
DRM_IOCTL_MODE_CURSOR2 would be dealt as success even if it
shouldn't.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-01 19:08:20 +02:00
Alex Goins
b83dede9cb modesetting: Implement PRIME syncing as a source
Implements (Start/Stop)FlippingPixmapTracking, PresentSharedPixmap, and
RequestSharedPixmapNotifyDamage, the source functions for PRIME
synchronization and double buffering. Allows modesetting driver to be used
as a source with PRIME synchronization.

v1: N/A
v2: N/A
v3: N/A
v4: Initial commit
v5: Move disabling of reverse PRIME on sink to sink commit
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:45 -04:00
Alex Goins
44cb9578c0 modesetting: Disable Reverse PRIME for i915
Reverse PRIME seems to be designed with discrete graphics as a sink in
mind, designed to do an extra copy from sysmem to vidmem to prevent a
discrete chip from needing to scan out from sysmem.

The criteria it used to detect this case is if we are a GPU screen and
Glamor accelerated. It's possible for i915 to fulfill these conditions,
despite the fact that the additional copy doesn't make sense for i915.

Normally, you could just set AccelMethod = none as an option for the device
and call it a day. However, when running with modesetting as both the sink
and the source, Glamor must be enabled.

Ideally, you would be able to set AccelMethod individually for devices
using the same driver, but there seems to be a bug in X option parsing that
makes all devices on a driver inherit the options from the first detected
device. Thus, glamor needs to be enabled for all or for none until that bug
(if it's even a bug) is fixed.

Nonetheless, it probably doesn't make sense to do the extra copy on i915
even if Glamor is enabled for the device, so this is more user friendly by
not requiring users to disable acceleration for i915.

v1: N/A
v2: N/A
v3: N/A
v4: Initial commit
v5: Unchanged
v6: Rebase onto ToT
v7: NULL check and free drmVersionPtr

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:43 -04:00
Alex Goins
f6fef2a171 modesetting: Blacklist USB transport devices from PRIME sync
UDL (USB 2.0 DisplayLink DRM driver) and other drivers for USB transport devices
have strange semantics when it comes to vblank events, due to their inability to
get the actual vblank info.

When doing a page flip, UDL instantly raises a vblank event without waiting for
vblank. It also has no support for DRM_IOCTL_WAIT_VBLANK, and has some strange
behavior with how it handles damage when page flipping.

It's possible to get something semi-working by hacking around these issues,
but even then there isn't much value-add vs single buffered PRIME, and it
reduces maintainability and adds additional risks to the modesetting driver
when running with more well-behaved DRM drivers.

Work needs to be done on UDL in order to properly support synchronized
PRIME. For now, just blacklist it, causing RandR to fall back to
unsynchronized PRIME.

This patch originally blacklisted UDL by name, but it was pointed out that there
are other USB transport device drivers with similar limitations, so it was
expanded to blacklist all USB transport devices.

v1: N/A
v2: N/A
v3: Initial commit
v4: Move check to driver.c for consistency/visibility
v5: Refactor to accomodate earlier changes
v6: Rebase onto ToT
v7: Expand to blacklist all USB transport devices, not just UDL

Signed-off-by: Alex Goins <agoins@nvidia.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-06-28 12:56:37 -04:00
Alex Goins
500853086d modesetting: Suspend and resume flipping with DPMS
DPMS would prevent page flip / vblank events from being raised, freezing
the screen until PRIME flipping was reinitialized. To handle DPMS cleanly,
suspend PRIME page flipping when DPMS mode is not on, and resume it when
DPMS mode is on.

v1: Initial commit
v2: Moved flipping_active check from previous commit to here
v3: Unchanged
v4: Unchanged
v5: Move flipping_active check to sink support commit
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:35 -04:00
Alex Goins
80e64dae8a modesetting: Implement PRIME syncing as a sink
Implements (Enable/Disable)SharedPixmapFlipping and
SharedPixmapNotifyDamage, the sink functions for PRIME synchronization and
double buffering. Allows modesetting driver to be used as a sink with PRIME
synchronization.

Changes dispatch_slave_dirty to flush damage from both scanout pixmaps.

Changes drmmode_set_scanout_pixmap*() functions to
drmmode_set_target_scanout_pixmap*() that take an additional parameter
PixmapPtr *target. Then, treat *target as it did prime_pixmap. This allows
me to use it to explicitly set both prime_pixmap and prime_pixmap_back
individually. drmmode_set_scanout_pixmap() without the extra parameter
remains to cover the single-buffered case, but only works if we aren't
already double buffered.

driver.c:
    Add plumbing for rr(Enable/Disable)SharedPixmapFlipping and
    SharedPixmapNotifyDamage.

    Change dispatch_dirty_crtc to dispatch_dirty_pixmap, which functions the
    same but flushes damage associated with a ppriv instead of the crtc, and
    chanage dispatch_slave_dirty to use it on both scanout pixmaps if
    applicable.

drmmode_display.h:
    Add flip_seq field to msPixmapPrivRec to keep track of the event handler
    associated with a given pixmap, if any.

    Add wait_for_damage field to msPixmapPrivRec to keep track if we have
    requested a damage notification from the source.

    Add enable_flipping field to drmmode_crtc_private_rec to keep track if
    flipping is enabled or disabled.

    Add prime_pixmap_back to drmmode_crtc_private_rec to keep track of back
    buffer internally.

    Add declarations for drmmode_SetupPageFlipFence(),
    drmmode_EnableSharedPixmapFlipping(),
    drmmode_DisableSharedPixmapFlipping, drmmode_SharedPixmapFlip(), and
    drmmode_SharedPixmapPresentOnVBlank().

    Move slave damage from crtc to ppriv.

drmmode_display.c:
    Change drmmode_set_scanout_pixmap*() functions to
    drmmode_set_target_scanout_pixmap*() that take an additional parameter
    PixmapPtr *target for explicitly setting different scanout pixmaps.

    Add definitions for functions drmmode_SharedPixmapFlip(),
    drmmode_SharedPixmapPresentOnVBlank(),
    drmmode_SharedPixmapPresent(),
    drmmode_SharedPixmapVBlankEventHandler(),
    drmmode_SharedPixmapVBlankEventAbort(),
    drmmode_EnableSharedPixmapFlipping(), and
    drmmode_DisableSharedPixmapFlipping,
    drmmode_InitSharedPixmapFlipping(), and
    drmmode_FiniSharedPixmapFlipping, along with struct
    vblank_event_args.

    The control flow is as follows:
        pScrPriv->rrEnableSharedPixmapFlipping() makes its way to
        drmmode_EnableSharedPixmapFlipping(), which sets enable_flipping to
        TRUE and sets both scanout pixmaps prime_pixmap and
        prime_pixmap_back.

        When setting a mode, if prime_pixmap is defined, modesetting
        driver will call drmmode_InitSharedPixmapFlipping(), which if
        flipping is enabled will call drmmode_SharedPixmapPresent() on
        scanout_pixmap_back.

        drmmode_SharedPixmapPresent() requests that for the source to
        present on the given buffer using master->PresentSharedPixmap(). If
        it succeeds, it will then attempt to flip to that buffer using
        drmmode_SharedPixmapFlip(). Flipping shouldn't fail, but if it
        does, it will raise a warning and try drmmode_SharedPixmapPresent()
        again on the next vblank using
        drmmode_SharedPixmapPresentOnVBlank().

        master->PresentSharedPixmap() could fail, in most cases because
        there is no outstanding damage on the mscreenpix tracked by the
        shared pixmap. In this case, drmmode_SharedPixmapPresent() will
        attempt to use master->RequestSharedPixmapNotifyDamage() to request
        for the source driver to call slave->SharedPixmapNotifyDamage() in
        response to damage on mscreenpix. This will ultimately call
        into drmmode_SharedPixmapPresentOnVBlank() to retry
        drmmode_SharedPixmapPresent() on the next vblank after
        accumulating damage.

        drmmode_SharedPixmapFlip() sets up page flip event handler by
        packing struct vblank_event_args with the necessary parameters, and
        registering drmmode_SharedPixmapVBlankEventHandler() and
        drmmode_SharedPixmapVBlankEventAbort() with the modesetting DRM
        event handler queue. Then, it uses the drmModePageFlip() to flip on
        the next vblank and raise an event.

        drmmode_SharedPixmapPresentOnVBlank() operates similarly to
        drmmode_SharedPixmapFlip(), but uses drmWaitVBlank() instead of
        drmModePageFlip() to raise the event without flipping.

        On the next vblank, DRM will raise an event that will ultimately be
        handled by drmmode_SharedPixmapVBlankEventHandler(). If we flipped,
        it will update prime_pixmap and prime_pixmap_back to reflect that
        frontTarget is now being displayed, and use
        drmmode_SharedPixmapPresent(backTarget) to start the process again
        on the now-hidden shared pixmap. If we didn't flip, it will just
        use drmmode_SharedPixmapPresent(frontTarget) to start the process
        again on the still-hidden shared pixmap.

        Note that presentation generally happens asynchronously, so with
        these changes alone tearing is reduced, but we can't always
        guarantee that the present will finish before the flip. These
        changes are meant to be paired with changes to the sink DRM driver
        that makes flips wait on fences attached to dmabuf backed buffers.
        The source driver is responsible for attaching the fences and
        signaling them when presentation is finished.

        Note that because presentation is requested in response to a
        vblank, PRIME sources will now conform to the sink's refresh rate.

        At teardown, pScrPriv->rrDisableSharedPixmapFlipping() will be
        called, making its way to drmmode_FiniSharedPixmapFlipping().
        There, the event handlers for prime_pixmap and prime_pixmap_back
        are aborted, freeing the left over parameter structure. Then,
        prime_pixmap and prime_pixmap back are unset as scanout pixmaps.

    Register and tear down slave damage per-scanout pixmap instead of
    per-crtc.

v1: Initial commit
v2: Renamed PresentTrackedFlippingPixmap to PresentSharedPixmap
    Renamed flipSeq to flip_seq
    Warn if flip failed
    Use SharedPixmapNotifyDamage to retry on next vblank after damage
v3: Refactor to accomodate moving (rr)StartFlippingPixmapTracking and
    (rr)(Enable/Disable)SharedPixmapFlipping to rrScrPrivRec from ScreenRec
    Do damage tracking on both scanout pixmaps
v4: Tweaks to commit message
v5: Revise for internal storage of prime pixmap ptrs
    Move disabling for reverse PRIME from source commit to here
    Use drmmode_set_target_scanout_pixmap*() to set scanout pixmaps
    internally to EnableSharedPixmapFlipping().
    Don't support flipping if ms->drmmode.pageflip == FALSE.
    Move flipping_active check to this commit
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:30 -04:00
Alex Goins
378c85a884 modesetting: Always load ms->drmmode.pageflip
ms->drmmode.pageflip was only loaded from options if ms->drmmode.glamor was
defined, otherwise it would always assume FALSE.

PRIME Synchronization requires ms->drmmode.pageflip even if we aren't using
glamor, so load it unconditionally.

v1: N/A
v2: N/A
v3: N/A
v4: N/A
v5: Initial commit
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:27 -04:00
Alex Goins
b773a9c812 modesetting: Always tear down scanout pixmap
drmmode_set_scanout_pixmap_(cpu/gpu) would only do teardown if ppix ==
NULL. This meant that if there were consecutive calls to
SetScanoutPixmap(ppix != NULL) without calls to SetScanoutPixmap(ppix ==
NULL) in between, earlier calls would be leaked.  RRReplaceScanoutPixmap()
does this today.

Instead, when setting a scanout pixmap, always do teardown of the existing
scanout pixmap before setting up the new one. Then, if there is no new one
to set up, stop there.

This maintains the previous behavior in all cases except those with
multiple consecutive calls to SetScanoutPixmap(ppix != NULL).

v1: N/A
v2: N/A
v3: N/A
v4: N/A
v5: Initial commit
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:25 -04:00
Alex Goins
f4c37eeee7 modesetting: Internal storage of scanout pixmaps
modesetting relied on randr_crtc->scanout_pixmap being consistent with
calls to SetScanoutPixmap, which is very fragile and makes a lot of
assumptions about the caller's behavior.

For example, RRReplaceScanoutPixmap(), when dropping off with !size_fits,
will set randr_crtc->scanout_pixmap = NULL and then call SetScanoutPixmap.
Without this patch, drmmode_set_scanout_pixmap_(cpu/gpu) will think that
there is no scanout pixmap to tear down, because it's already been set to
NULL.

By keeping track of the scanout pixmap in its internal state, modesetting
can avoid these types of bugs and reduce constraints on calling
conventions.

v1: N/A
v2: N/A
v3: N/A
v4: N/A
v5: Initial commit
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:21 -04:00
Alex Goins
1bdbc7e764 randr/xf86: Add PRIME Synchronization / Double Buffer
Changes PRIME to use double buffering and synchronization if all required
driver functions are available.

rrcrtc.c:
    Changes rrSetupPixmapSharing() to use double buffering and
    synchronization in the case that all required driver functions are
    available. Otherwise, falls back to unsynchronized single buffer.

    Changes RRCrtcDetachScanoutPixmap() to properly clean up in the case of
    double buffering.

    Moves StopPixmapTracking() from rrDestroySharedPixmap() to
    RRCrtcDetachScanoutPixmap().

    Changes RRReplaceScanoutPixmap() to fail if we are using double buffering,
    as it would need a second ppix parameter to function with double buffering,
    and AFAICT no driver I've implemented double buffered source support in uses
    RRReplaceScanoutPixmap().

randrstr.h:
    Adds scanout_pixmap_back to struct _rrCrtc to facilitate PRIME
    double buffering.

xf86Crtc.h:
    Adds current_scanout_back to _xf86Crtc to facilitate detection
    of changes to it in xf86RandR12CrtcSet().

xf86RandR12.c:
    Changes xf86RandR12CrtcSet() to detect changes in
    scanout_pixmap_back.

    Adds scanout_pixmap_back to struct _rrCrtc to facilitate PRIME double
    buffering.

v1: Initial commit
v2: Rename PresentTrackedFlippingPixmap to PresentSharedPixmap
v3: Refactor to accomodate moving (rr)StartFlippingPixmapTracking and
    (rr)(Enable/Disable)SharedPixmapFlipping to rrScrPrivRec from ScreenRec
    Add fallback if flipping funcs fail
v4: Detach scanout pixmap when destroying scanout_pixmap_back, to avoid
    dangling pointers in some drivers
v5: Disable RRReplaceScanoutPixmap for double-buffered PRIME, it would need an
    ABI change with support for 2 pixmaps if it were to be supported, but AFAICT
    no driver that actually supports double-buffered PRIME uses it.
    Refactor to use rrEnableSharedPixmapFlipping() as a substitute for
    rrCrtcSetScanoutPixmap() in the flipping case.
    Remove extraneous pSlaveScrPriv from DetachScanoutPixmap()
    Remove extraneous protopix and pScrPriv from rrSetupPixmapSharing()
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:17 -04:00
Michel Dänzer
263c5333a5 xfree86/modes: Simplify in_range logic in xf86_crtc_set_cursor_position
Consolidate to a single if/else statement and eliminate the redundant
local variable in_range and assignments to x/y.

Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-06-21 10:40:05 +09:00
Michel Dänzer
a991b1ec30 xfree86/modes: Disambiguate driverIsPerformingTransform
The driver can now specify exactly which aspects of the transform it
wants to handle via XF86DriverTransform* flags.

Since the driver can now choose whether it wants to receive transformed
or untransformed cursor coordinates, xf86CrtcTransformCursorPos no
longer needs to be available to drivers, so make it static.

Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-06-21 10:39:13 +09:00
Michel Dänzer
aad96f8500 xfree86/modes: Fix HW cursor clipping for driverIsPerformingTransform (v2)
Even if the driver is handling the transform, we still need to transform
the cursor position for clipping, otherwise we may hide the HW cursor
when the cursor is actually inside the area covered by the CRTC.

v2: Use crtc_x/y local variables for clarity

Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-06-21 10:38:37 +09:00
Lyude Paul
848089e0dd modesetting: Clear drmmode->fb_id before unflipping
[fix copied from 40191d82370e in xf86-video-ati]

Without this, we end up setting rotated CRTCs back to their previous
framebuffer right after we perform a rotation. Reproducer:

- Have two monitors connected at the same resolution
- Rotate one monitor from normal straight to inverted
- Watch as the monitor you didn't rotate either freezes or shows intense
  flickering

Signed-off-by: Lyude <cpaul@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-06-17 11:38:13 +02:00
Hans de Goede
4313122dea modesetting: Only add main fb if necessary
If we're doing reverse-prime; or doing rotation the main fb is not used,
and there is no reason to add it in this case.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-06-17 11:38:13 +02:00
Hans de Goede
8774532121 modesetting: Remove unnecessary fb addition from drmmode_xf86crtc_resize
drmmode_set_mode_major() is the only user of drmmode->fb_id and will
create it if necessary.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-06-17 11:38:13 +02:00
Hans de Goede
210d83ad49 modesetting: Set ppix->fb_id to 0 after removing the fb
This ensures the fb gets re-added when a shared pixmap is re-used for
a second drmmode_set_scanout_pixmap_cpu call.

Note currently the xserver never re-uses a shared pixmap in this way,
so this is mostly a sanity fix.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-06-17 11:38:13 +02:00
Hans de Goede
b8ef71fb07 modesetting: Properly cleanup fb for reverse-prime-offload
drmmode_set_scanout_pixmap_gpu(pix) adds drmmod->fb_id through a call
to drmmode_xf86crtc_resize(), but on a subsequent
drmmode_set_scanout_pixmap_gpu(NULL) it would not remove the fb.

This keeps the crtc marked as busy, which causes the dgpu to not
being able to runtime suspend, after an output attached to the dgpu
has been used once. Which causes burning through an additional 10W
of power and the laptop to run quite hot.

This commit adds the missing remove fb call, allowing the dgpu to runtime
suspend after an external monitor has been plugged into the laptop.

Note this also makes drmmode_set_scanout_pixmap_gpu(NULL) match the
behavior of drmmode_set_scanout_pixmap_cpu(NULL) which was already
removing the fb.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-06-17 11:38:13 +02:00
Hans de Goede
5c7af02b10 xrandrprovider: Do not use separate lists for unbound / source / offload slaves
A single provider can be both a offload and source slave at the same time,
the use of seperate lists breaks in this case e.g. :

xrandr --listproviders
Providers: number : 2
Provider 0: id: 0x7b cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 2 associated providers: 0 name:modesetting
Provider 1: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 0 name:modesetting

xrandr --setprovideroutputsource 1 0x7b
xrandr --listproviders
Providers: number : 2
Provider 0: id: 0x7b cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 2 associated providers: 1 name:modesetting
Provider 1: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 1 name:modesetting

xrandr --setprovideroffloadsink 1 0x7b
xrandr --listproviders
Providers: number : 3
Provider 0: id: 0x7b cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 2 associated providers: 2 name:modesetting
Provider 1: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 2 name:modesetting
Provider 2: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 2 name:modesetting

Not good. The problem is that the provider with id 0x46 now is on both
the output_slave_list and the offload_slave_list of the master screen.

This commit fixes this by unifying all 3 lists into a single slaves list.

Note that this does change the struct _Screen definition, so this is an ABI
break. I do not expect any of the drivers to actually use the removed / changed
fields so a recompile should suffice.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-06-17 11:35:58 +02:00
Eric Biggers
da9fec4edd Allow ConstantDeceleration < 1.0
As documented in xorg.conf(5), a value of ConstantDeceleration between 0
and 1 will speed up the pointer.  However, values less than 1 actually
had no effect.  Fix this.

Note that this bug only affected "ConstantDeceleration" as configured
through xorg.conf, not "Device Accel Constant Deceleration" as configured
through xinput.  The property handler AccelSetDecelProperty() also did
not need to be changed, as it did not limit the values of the property.

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=92766

Signed-off-by: Eric Biggers <ebiggers3@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-06-10 10:54:48 +10:00
Adam Jackson
7cf80b9714 xfree86: Don't swallow ±iglx command line flag
We want to notice that it's set, but still pass it through to dix.
Return 0 to indicate this.

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-06-08 13:15:57 -04:00
Peter Hutterer
c69bd15e00 Allow compile-time selection of a fallback input driver
A new --with-fallback-input-driver=foo option allows selecting a
fallback driver for the server if the driver configured for the device
is not found.  Note that this only applies when the device has a driver
assigned and that module fails to load, devices without a driver are
ignored as usual.

This avoids the situation where a configuration assigns e.g. the
synaptics driver but that driver is not available on the system,
resulting in a dead device. A fallback driver can at least provides some
functionality.

This becomes more important as we move towards making other driver true
leaf nodes that can be installed/uninstalled as requested. Specifically,
wacom and synaptics, a config that assigns either driver should be
viable even when the driver itself is not (yet) installed on the system.

It is up to the distributions to make sure that the fallback driver is
always installed. The fallback driver can be disabled with
--without-fallback-input-driver and is disabled by default on non-Linux
systems because we don't have generic drivers on those platforms.
Default driver on Linux is libinput, evdev is the only other serious
candidate here.

Sample log output:
[  3274.421] (II) config/udev: Adding input device SynPS/2 Synaptics TouchPad (/dev/input/event4)
[  3274.421] (**) SynPS/2 Synaptics TouchPad: Applying InputClass "touchpad weird driver"
[  3274.421] (II) LoadModule: "banana"
[  3274.422] (WW) Warning, couldn't open module banana
[  3274.422] (II) UnloadModule: "banana"
[  3274.422] (II) Unloading banana
[  3274.422] (EE) Failed to load module "banana" (module does not exist, 0)
[  3274.422] (EE) No input driver matching `banana'
[  3274.422] (II) Falling back to input driver `libinput'
.. server proceeds to assign libinput, init the device, world peace and rainbows
everywhere, truly what a sight. Shame about the banana though.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-06-08 13:08:32 -04:00