[PATCH] xfree86: Remove redundant ServerIsNotSeat0 check from xf86CallDriverProbe

2016-09-30 Thread Hans de Goede
If foundScreen is TRUE, then all the code below the removed if
will not execute until we reach the return foundScreen; at the
end, so this entire if block is redundant.

Signed-off-by: Hans de Goede 
---
 hw/xfree86/common/xf86Bus.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 5b93940..27c6b1b 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -82,8 +82,6 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only)
 if (!xf86DoConfigure && drv->platformProbe != NULL) {
 foundScreen = xf86platformProbeDev(drv);
 }
-if (ServerIsNotSeat0() && foundScreen)
-return foundScreen;
 #endif
 
 #ifdef XSERVER_LIBPCIACCESS
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH 1/2] xfree86: Make adding unclaimed devices as GPU devices a separate step

2016-09-30 Thread Hans de Goede
This is primarily a preparation patch for fixing the xserver exiting with
a "no screens found" error even though there are supported video cards,
due to the server not recognizing any card as the primary card.

This also fixes the (mostly theoretical) case of a platformBus capable
driver adding a device as GPUscreen before a driver which only supports
the old PCI probe method gets a chance to claim it as a normal screen.

Signed-off-by: Hans de Goede 
---
 hw/xfree86/common/xf86Bus.c |  4 
 hw/xfree86/common/xf86platformBus.c | 15 +++
 hw/xfree86/common/xf86platformBus.h |  6 ++
 3 files changed, 25 insertions(+)

diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 27c6b1b..a3a9898 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -125,6 +125,10 @@ xf86BusConfig(void)
 xf86CallDriverProbe(xf86DriverList[i], FALSE);
 }
 
+for (i = 0; i < xf86NumDrivers; i++) {
+xf86platformAddGPUDevices(xf86DriverList[i]);
+}
+
 /* If nothing was detected, return now */
 if (xf86NumScreens == 0) {
 xf86Msg(X_ERROR, "No devices detected.\n");
diff --git a/hw/xfree86/common/xf86platformBus.c 
b/hw/xfree86/common/xf86platformBus.c
index 3e2264f..ec2a1dd 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -476,6 +476,21 @@ xf86platformProbeDev(DriverPtr drvp)
 isGPUDevice(devList[i]) ? 
PLATFORM_PROBE_GPU_SCREEN : 0);
 }
 
+return foundScreen;
+}
+
+int
+xf86platformAddGPUDevices(DriverPtr drvp)
+{
+Bool foundScreen = FALSE;
+GDevPtr *devList;
+int j;
+
+if (!drvp->platformProbe)
+return FALSE;
+
+xf86MatchDevice(drvp->driverName, &devList);
+
 /* if autoaddgpu devices is enabled then go find any unclaimed platform
  * devices and add them as GPU screens */
 if (xf86Info.autoAddGPU) {
diff --git a/hw/xfree86/common/xf86platformBus.h 
b/hw/xfree86/common/xf86platformBus.h
index a7335b9..0f5c0ef 100644
--- a/hw/xfree86/common/xf86platformBus.h
+++ b/hw/xfree86/common/xf86platformBus.h
@@ -41,6 +41,7 @@ struct xf86_platform_device {
 #ifdef XSERVER_PLATFORM_BUS
 int xf86platformProbe(void);
 int xf86platformProbeDev(DriverPtr drvp);
+int xf86platformAddGPUDevices(DriverPtr drvp);
 
 extern int xf86_num_platform_devices;
 extern struct xf86_platform_device *xf86_platform_devices;
@@ -156,6 +157,11 @@ xf86PlatformMatchDriver(char *matches[], int nmatches);
 
 extern void xf86platformVTProbe(void);
 extern void xf86platformPrimary(void);
+
+#else
+
+static inline int xf86platformAddGPUDevices(DriverPtr drvp) { return FALSE; }
+
 #endif
 
 #endif
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH 2/2] xfree86: Try harder to find atleast 1 non GPU Screen

2016-09-30 Thread Hans de Goede
If we did not find any non GPU Screens, try again ignoring the notion
of any video devices being the primary device. This fixes Xorg exiting
with a "no screens found" error when using virtio-vga in a
virtual-machine and when using a device driven by simpledrm.

This is a somewhat ugly solution, but it is the best I can come up with
without major surgery to the bus and probe code.

Signed-off-by: Hans de Goede 
---
 hw/xfree86/common/xf86.h|  1 +
 hw/xfree86/common/xf86Bus.c | 26 +++---
 hw/xfree86/common/xf86Globals.c |  1 +
 hw/xfree86/common/xf86pciBus.c  |  4 
 hw/xfree86/common/xf86platformBus.c |  4 
 5 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index e54c811..f724688 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -55,6 +55,7 @@
 extern _X_EXPORT int xf86DoConfigure;
 extern _X_EXPORT int xf86DoShowOptions;
 extern _X_EXPORT Bool xf86DoConfigurePass1;
+extern _X_EXPORT Bool xf86ProbeIgnorePrimary;
 extern _X_EXPORT Bool xorgHWAccess;
 
 extern _X_EXPORT DevPrivateKeyRec xf86ScreenKeyRec;
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index a3a9898..9836803 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -117,14 +117,34 @@ xf86BusConfig(void)
 int i, j;
 
 /*
- * Now call each of the Probe functions.  Each successful probe will
- * result in an extra entry added to the xf86Screens[] list for each
- * instance of the hardware found.
+ * 3 step probe to (hopefully) ensure that we always find at least 1
+ * (non GPU) screen:
+ *
+ * 1. Call each drivers probe function normally,
+ *Each successful probe will result in an extra entry added to the
+ *xf86Screens[] list for each instance of the hardware found.
  */
 for (i = 0; i < xf86NumDrivers; i++) {
 xf86CallDriverProbe(xf86DriverList[i], FALSE);
 }
 
+/*
+ * 2. If no Screens were found, call each drivers probe function with
+ *ignorePrimary = TRUE, to ensure that we do actually get a
+ *Screen if there is atleast one supported video card.
+ */
+if (xf86NumScreens == 0) {
+xf86ProbeIgnorePrimary = TRUE;
+for (i = 0; i < xf86NumDrivers && xf86NumScreens == 0; i++) {
+xf86CallDriverProbe(xf86DriverList[i], FALSE);
+}
+xf86ProbeIgnorePrimary = FALSE;
+}
+
+/*
+ * 3. Call xf86platformAddGPUDevices() to add any additional video cards as
+ *GPUScreens (GPUScreens are only supported by platformBus drivers).
+ */
 for (i = 0; i < xf86NumDrivers; i++) {
 xf86platformAddGPUDevices(xf86DriverList[i]);
 }
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 072c3fc..0d1e31b 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -153,6 +153,7 @@ XF86ConfigPtr xf86configptr = NULL;
 Bool xf86Resetting = FALSE;
 Bool xf86Initialising = FALSE;
 Bool xf86DoConfigure = FALSE;
+Bool xf86ProbeIgnorePrimary = FALSE;
 Bool xf86DoShowOptions = FALSE;
 DriverPtr *xf86DriverList = NULL;
 int xf86NumDrivers = 0;
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 8158c2b..9adfee5 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -352,6 +352,10 @@ xf86ComparePciBusString(const char *busID, int bus, int 
device, int func)
 Bool
 xf86IsPrimaryPci(struct pci_device *pPci)
 {
+/* Add max. 1 screen for the IgnorePrimary fallback path */
+if (xf86ProbeIgnorePrimary && xf86NumScreens == 0)
+return TRUE;
+
 if (primaryBus.type == BUS_PCI)
 return pPci == primaryBus.id.pci;
 #ifdef XSERVER_PLATFORM_BUS
diff --git a/hw/xfree86/common/xf86platformBus.c 
b/hw/xfree86/common/xf86platformBus.c
index ec2a1dd..fde6796 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -115,6 +115,10 @@ xf86_find_platform_device_by_devnum(int major, int minor)
 static Bool
 xf86IsPrimaryPlatform(struct xf86_platform_device *plat)
 {
+/* Add max. 1 screen for the IgnorePrimary fallback path */
+if (xf86ProbeIgnorePrimary && xf86NumScreens == 0)
+return TRUE;
+
 if (primaryBus.type == BUS_PLATFORM)
 return plat == primaryBus.id.plat;
 #ifdef XSERVER_LIBPCIACCESS
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver] os/xdmcp: Honour -once when session is dead

2016-09-30 Thread Daniel Martin
Terminate a dead session when -once was passed. Don't restart it.

Signed-off-by: Daniel Martin 
---
 os/xdmcp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/os/xdmcp.c b/os/xdmcp.c
index 906c959..7aeb393 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -797,7 +797,7 @@ XdmcpDeadSession(const char *reason)
 ErrorF("XDM: %s, declaring session dead\n", reason);
 state = XDM_INIT_STATE;
 isItTimeToYield = TRUE;
-dispatchException |= DE_RESET;
+dispatchException |= (OneSession ? DE_TERMINATE : DE_RESET);
 TimerCancel(xdmcp_timer);
 timeOutRtx = 0;
 send_packet();
-- 
2.10.0

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver] glamor: Accelerate XYBitmap PutImage

2016-09-30 Thread Adam Jackson
XYBitmap to a drawable of depth != 1 is special. Where bits are 1, we
draw the foreground color; where they are 0, we draw the background
color. To handle this without falling back, allocate a temporary pixmap,
do the color expansion in software, and then upload that image to the
destination.

This could probably be made faster if GL exposed an R1 texture format.

Signed-off-by: Adam Jackson 
---
 glamor/glamor_image.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 3158749..699bdb8 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -24,6 +24,33 @@
 #include "glamor_transfer.h"
 #include "glamor_transform.h"
 
+static PixmapPtr
+glamor_expand_bitmap(DrawablePtr drawable, GCPtr src, int w, int h, char *bits)
+{
+ScreenPtr screen = drawable->pScreen;
+PixmapPtr ret;
+GCPtr gc;
+ChangeGCVal v[2];
+
+if (!(gc = GetScratchGC(drawable->depth, screen)))
+return NULL;
+
+ret = screen->CreatePixmap(screen, w, h, drawable->depth,
+   GLAMOR_CREATE_PIXMAP_CPU);
+
+if (ret) {
+DrawablePtr scratch = &ret->drawable;
+v[0].val = src->fgPixel;
+v[1].val = src->bgPixel;
+ChangeGC(serverClient, gc, GCForeground | GCBackground, v);
+ValidateGC(scratch, gc);
+fbPutImage(scratch, gc, gc->depth, 0, 0, w, h, 0, XYBitmap, bits);
+}
+
+FreeScratchGC(gc);
+return ret;
+}
+
 /*
  * PutImage. Only does ZPixmap right now as other formats are quite a bit 
harder
  */
@@ -35,6 +62,7 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int 
depth, int x, int y,
 ScreenPtr screen = drawable->pScreen;
 glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+PixmapPtr tmp = NULL;
 glamor_pixmap_private *pixmap_priv;
 uint32_tbyte_stride = PixmapBytePad(w, drawable->depth);
 RegionRec   region;
@@ -55,6 +83,14 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int 
depth, int x, int y,
 if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
 format = ZPixmap;
 
+if (format == XYBitmap && leftPad == 0) {
+if (!(tmp = glamor_expand_bitmap(drawable, gc, w, h, bits)))
+goto bail;
+
+bits = tmp->devPrivate.ptr;
+format = ZPixmap;
+}
+
 if (format != ZPixmap)
 goto bail;
 
@@ -79,6 +115,10 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int 
depth, int x, int y,
 glamor_upload_region(pixmap, ®ion, x, y, (uint8_t *) bits, byte_stride);
 
 RegionUninit(®ion);
+
+if (tmp)
+fbDestroyPixmap(tmp);
+
 return TRUE;
 bail:
 return FALSE;
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH] glamor: spans: fixup wrong count on glDrawArrays

2016-09-30 Thread Eric Anholt
Mark Yao  writes:

> since commit (9e9fcf5 glamor: Add a helper function for the common
> GL_QUADS fallback pattern.), the glDrawArrays count change to nbox,
> That is wrong, I think it maybe cause by fat finger.
>
> Signed-off-by: Mark Yao 

Thanks!  This fixes xlogo on a GL 2.1 implementation.

I need to rig up testing for 2.1 specifically -- we've had plenty of
breakage on it at this point.


signature.asc
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH xserver] modesetting: always set a hardware cursor when requested to load one.

2016-09-30 Thread Michael Thayer

Hello Hans,

On 29.09.2016 09:56, Hans de Goede wrote:

Hi,

On 28-09-16 16:54, Michael Thayer wrote:

Hello Hans,

On 28.09.2016 15:37, Hans de Goede wrote:

Hi Michael,

On 28-09-16 14:47, Michael Thayer wrote:

[...]

On 09/16/2016 06:52 PM, Michael Thayer wrote:

When the X server asks us to load a hardware cursor, that
request is always followed up by a request to show it if we
report success, or to hide it if we report failure.  Therefore
it makes no sense to suppress the request if the cursor is not
currently visible.

[...]

For the record, I looked at making show_cursor() return a boolean.  It
seemed feasible, and would allow for removing the first time hack in
modesetting too


Making show_cursor return an error (adding a show_cursor_check()) seems
to be the best solution to me, we actually had a patch submitted for
this, but it was deemed unnecessary. I guess it is necessary after all:

https://patchwork.freedesktop.org/patch/94495/


but there was a catch in that the cursor could theoretically be
visible but still hidden on all screens (with a strange screen layout),


Yes that is possible.


in which case show_cursor() would not be called until the cursor moved

onto a screen.

Ack.


 Making set_cursor_position() return a success value seemed a bit too
invasive.


But in the scenario you describe it is not the drivers
set_cursor_position()
which will get called (well not only) also the drivers' show_cursor will
get
called on the crtc where the cursor should now show, so just making
show_cursor
return an error should be enough.

[...]

Right, xf86_crtc_set_cursor_position() calls the driver's
show_cursor().  What I meant was that that means that this function
can now fail, and that failure needs to be propagated up and probably
handled in xf86CursorMoveCursor() by reverting to a software cursor
there.  The alternative is another first time-style hack (if we are
asked to show the cursor and it is not in range of any of the crtc-s
then flicker it).


Hmm, so 2 things:

1) We definitely do not want another first-time hack, so if we really
need to lets do the propagate error thing
2) Thinking about holes in crtc layouts again, I think the xrandr cursor
constraint code will warp the pointer to
the closest crtc then (pretty sure actually) so I think this is a non
issue. So just rebasing the patch I linked
(and dropping the first time hack) should be enough. And since we're
planning to do this for 1.20, I think we
should just try doing things that way, we've an entire cycle to catch
any issues then (which I do not believe
there will be)


I rebased Alexandre's patch (not sure if there is an official way to 
credit someone, I just did so in the commit message) as two new patches, 
one to xfree86 and one to modesetting (in which I also got rid of the 
first time hack), both slightly adjusted to be more like existing code. 
I rebased my software-back-to-hardware on top of that.


I did not follow all code paths in detail, but it does look to me as if 
what you said about the constraint code is what is intended (can someone 
who knows RandR confirm?), so that if it does not work then it is the 
constraint code which should be fixed.


I tested that switching to a software cursor happens as soon as 
drmmode_show_cursor() is called, that the test for hardware cursor 
support is repeated on every show or set call, and although I can't 
confirm visually (we only have a single hardware cursor, not one per 
crtc), I checked as best I could using break-points in gdb that showing 
and hiding cursors happened correctly on multiple screens.  Feel free to 
suggest additional tests.


Patches coming up.

Regards,

Michael


Regards,

Hans






Regards,

Michael


--
Michael Thayer | VirtualBox engineer
ORACLE Deutschland B.V. & Co. KG | Werkstr. 24 | D-71384 Weinstadt

ORACLE Deutschland B.V. & Co. KG
Hauptverwaltung: Riesstraße 25, D-80992 München
Registergericht: Amtsgericht München, HRA 95603

Komplementärin: ORACLE Deutschland Verwaltung B.V.
Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister 
der Handelskammer Midden-Nederland, Nr. 30143697

Geschäftsführer: Alexander van der Ven, Jan Schultheiss, Val Maher
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver 1/3] xfree86: Immediately handle failure to set HW cursor, v5

2016-09-30 Thread Michael Thayer
Based on v4 by Alexandre Courbot 

There is currently no reliable way to report failure to set a HW
cursor. Still such failures can happen if e.g. the MODE_CURSOR DRM
ioctl fails (which currently happens at least with modesetting on Tegra
for format incompatibility reasons).

As failures are currently handled by setting the HW cursor size to
(0,0), the fallback to SW cursor will not happen until the next time the
cursor changes and xf86CursorSetCursor() is called again. In the
meantime, the cursor will be invisible to the user.

This patch addresses that by adding _xf86CrtcFuncs::set_cursor_check and
_xf86CursorInfoRec::ShowCursorCheck hook variants that return booleans.
This allows to propagate errors up to xf86CursorSetCursor(), which can
then fall back to using the SW cursor immediately.

v5: Updated the patch to apply to current git HEAD, split up into two
patches (server and modesetting driver) and adjusted the code slightly
to match surrounding code.  I also removed the new exported function
ShowCursorCheck(), as instead just changing ShowCursor() to return Bool
should not affect its current callers.

Signed-off-by: Michael Thayer 
---
 hw/xfree86/modes/xf86Crtc.h|  4 +++-
 hw/xfree86/modes/xf86Cursors.c | 40 ++--
 hw/xfree86/ramdac/xf86Cursor.h | 16 
 hw/xfree86/ramdac/xf86HWCurs.c |  8 
 4 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 14ba9d7..215eb2a 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -195,6 +195,8 @@ typedef struct _xf86CrtcFuncs {
  */
 void
  (*show_cursor) (xf86CrtcPtr crtc);
+Bool
+ (*show_cursor_check) (xf86CrtcPtr crtc);
 
 /**
  * Hide cursor
@@ -993,7 +995,7 @@ static _X_INLINE _X_DEPRECATED void 
xf86_reload_cursors(ScreenPtr screen) {}
 /**
  * Called from EnterVT to turn the cursors back on
  */
-extern _X_EXPORT void
+extern _X_EXPORT Bool
  xf86_show_cursors(ScrnInfoPtr scrn);
 
 /**
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 1bc2b27..9543eed 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -210,9 +210,15 @@ set_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int 
x, int y, Bool mask)
 
 /*
  * Wrappers to deal with API compatibility with drivers that don't expose
- * load_cursor_*_check
+ * *_cursor_*_check
  */
 static inline Bool
+xf86_driver_has_show_cursor(xf86CrtcPtr crtc)
+{
+return crtc->funcs->show_cursor_check || crtc->funcs->show_cursor;
+}
+
+static inline Bool
 xf86_driver_has_load_cursor_image(xf86CrtcPtr crtc)
 {
 return crtc->funcs->load_cursor_image_check || 
crtc->funcs->load_cursor_image;
@@ -225,6 +231,15 @@ xf86_driver_has_load_cursor_argb(xf86CrtcPtr crtc)
 }
 
 static inline Bool
+xf86_driver_show_cursor(xf86CrtcPtr crtc)
+{
+if (crtc->funcs->show_cursor_check)
+return crtc->funcs->show_cursor_check(crtc);
+crtc->funcs->show_cursor(crtc);
+return TRUE;
+}
+
+static inline Bool
 xf86_driver_load_cursor_image(xf86CrtcPtr crtc, CARD8 *cursor_image)
 {
 if (crtc->funcs->load_cursor_image_check)
@@ -333,16 +348,19 @@ xf86_hide_cursors(ScrnInfoPtr scrn)
 }
 }
 
-static void
+static Bool
 xf86_crtc_show_cursor(xf86CrtcPtr crtc)
 {
-if (!crtc->cursor_shown && crtc->cursor_in_range) {
-crtc->funcs->show_cursor(crtc);
-crtc->cursor_shown = TRUE;
-}
+if (!crtc->cursor_in_range)
+return TRUE;
+
+if (!crtc->cursor_shown)
+crtc->cursor_shown = xf86_driver_show_cursor(crtc);
+
+return crtc->cursor_shown;
 }
 
-void
+Bool
 xf86_show_cursors(ScrnInfoPtr scrn)
 {
 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -352,9 +370,11 @@ xf86_show_cursors(ScrnInfoPtr scrn)
 for (c = 0; c < xf86_config->num_crtc; c++) {
 xf86CrtcPtr crtc = xf86_config->crtc[c];
 
-if (crtc->enabled)
-xf86_crtc_show_cursor(crtc);
+if (crtc->enabled && !xf86_crtc_show_cursor(crtc))
+return FALSE;
 }
+
+return TRUE;
 }
 
 static void
@@ -653,7 +673,7 @@ xf86_cursors_init(ScreenPtr screen, int max_width, int 
max_height, int flags)
 cursor_info->SetCursorPosition = xf86_set_cursor_position;
 cursor_info->LoadCursorImageCheck = xf86_load_cursor_image;
 cursor_info->HideCursor = xf86_hide_cursors;
-cursor_info->ShowCursor = xf86_show_cursors;
+cursor_info->ShowCursorCheck = xf86_show_cursors;
 cursor_info->UseHWCursor = xf86_use_hw_cursor;
 if (flags & HARDWARE_CURSOR_ARGB) {
 cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
diff --git a/hw/xfree86/ramdac/xf86Cursor.h b/hw/xfree86/ramdac/xf86Cursor.h
index 320ec0c..11a03b6 100644
--- a/hw/xfree86/ramdac/xf86Cursor.h
+++ b/hw/xfree86/ramdac/xf86Cursor.h
@@ -16,6 +16,7 @@ typedef struct _xf86CursorInfoRec {
 Bool (*LoadCursorImageCheck) (ScrnInfoPtr pScrn, unsigned c

[PATCH xserver 2/3] modesetting: Immediately handle failure to set HW cursor, v5

2016-09-30 Thread Michael Thayer
Based on v4 by Alexandre Courbot 

There is currently no reliable way to report failure to set a HW
cursor. Still such failures can happen if e.g. the MODE_CURSOR DRM
ioctl fails (which currently happens at least with modesetting on Tegra
for format incompatibility reasons).

As failures are currently handled by setting the HW cursor size to
(0,0), the fallback to SW cursor will not happen until the next time the
cursor changes and xf86CursorSetCursor() is called again. In the
meantime, the cursor will be invisible to the user.

This patch addresses that by adding _xf86CrtcFuncs::set_cursor_check and
_xf86CursorInfoRec::ShowCursorCheck hook variants that return booleans.
This allows to propagate errors up to xf86CursorSetCursor(), which can
then fall back to using the SW cursor immediately.

v5:
 - Removed parts of patch already committed as part of 14c21ea1.
 - Adjusted code slightly to match surrounding code.
 - Effectively reverted af916477 which is made unnecessary by this patch.

Signed-off-by: Michael Thayer 
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 15 +--
 hw/xfree86/drivers/modesetting/drmmode_display.h |  1 -
 2 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c 
b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 61a0e27..8e68c0e 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -813,13 +813,8 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 
*image)
 for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
 ptr[i] = image[i];  // cpu_to_le32(image[i]);
 
-if (drmmode_crtc->cursor_up || !drmmode_crtc->first_cursor_load_done) {
-Bool ret = drmmode_set_cursor(crtc);
-if (!drmmode_crtc->cursor_up)
-drmmode_hide_cursor(crtc);
-drmmode_crtc->first_cursor_load_done = TRUE;
-return ret;
-}
+if (drmmode_crtc->cursor_up)
+return drmmode_set_cursor(crtc);
 return TRUE;
 }
 
@@ -835,12 +830,12 @@ drmmode_hide_cursor(xf86CrtcPtr crtc)
  ms->cursor_width, ms->cursor_height);
 }
 
-static void
+static Bool
 drmmode_show_cursor(xf86CrtcPtr crtc)
 {
 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 drmmode_crtc->cursor_up = TRUE;
-drmmode_set_cursor(crtc);
+return drmmode_set_cursor(crtc);
 }
 
 static void
@@ -1108,7 +1103,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
 .set_mode_major = drmmode_set_mode_major,
 .set_cursor_colors = drmmode_set_cursor_colors,
 .set_cursor_position = drmmode_set_cursor_position,
-.show_cursor = drmmode_show_cursor,
+.show_cursor_check = drmmode_show_cursor,
 .hide_cursor = drmmode_hide_cursor,
 .load_cursor_argb_check = drmmode_load_cursor_argb_check,
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h 
b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 50976b8..3b0eb2b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -93,7 +93,6 @@ typedef struct {
 struct dumb_bo *cursor_bo;
 Bool cursor_up;
 Bool set_cursor2_failed;
-Bool first_cursor_load_done;
 uint16_t lut_r[256], lut_g[256], lut_b[256];
 
 drmmode_bo rotate_bo;
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver 3/3] modesetting: allow switching from software to hardware cursors (v5).

2016-09-30 Thread Michael Thayer
Currently if modesetting ever fails to set a hardware cursor it will switch
to using a software cursor and never go back.  Change this to only
permanently switch to a software cursor if -ENXIO is returned (which means
hardware cursors not supported), and to otherwise still try a hardware
cursor first every time a new one is set.  This is needed because hardware
may be able to handle some cursors in hardware and others not, or virtual
hardware may be able to handle hardware cursors at some times and not
others.

Changes since v1, v2 and v3:
 * take into account the switch to load_cursor_argb_check
 * keep the permanent software cursor fall-back if -ENXIO is returned
 * move parts of v3 into separate patches

Signed-off-by: Michael Thayer 
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 30 ++--
 hw/xfree86/drivers/modesetting/drmmode_display.h |  1 -
 2 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c 
b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 8e68c0e..bbe1a5f 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -756,37 +756,33 @@ drmmode_set_cursor(xf86CrtcPtr crtc)
 drmmode_ptr drmmode = drmmode_crtc->drmmode;
 uint32_t handle = drmmode_crtc->cursor_bo->handle;
 modesettingPtr ms = modesettingPTR(crtc->scrn);
+CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
 int ret = -EINVAL;
 
-if (!drmmode_crtc->set_cursor2_failed) {
-CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
-
-ret =
-drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-  handle, ms->cursor_width, ms->cursor_height,
-  cursor->bits->xhot, cursor->bits->yhot);
-if (!ret)
-return TRUE;
-
-/* -EINVAL can mean that an old kernel supports drmModeSetCursor but
- * not drmModeSetCursor2, though it can mean other things too. */
-if (ret == -EINVAL)
-drmmode_crtc->set_cursor2_failed = TRUE;
-}
+ret = drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+handle, ms->cursor_width, ms->cursor_height,
+cursor->bits->xhot, cursor->bits->yhot);
 
+/* -EINVAL can mean that an old kernel supports drmModeSetCursor but
+ * not drmModeSetCursor2, though it can mean other things too. */
 if (ret == -EINVAL)
 ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
handle, ms->cursor_width, ms->cursor_height);
 
-if (ret) {
+/* -ENXIO normally means that the current drm driver supports neither
+ * cursor_set nor cursor_set2.  Disable hardware cursor support for
+ * the rest of the session in that case. */
+if (ret == -ENXIO) {
 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
 
 cursor_info->MaxWidth = cursor_info->MaxHeight = 0;
 drmmode_crtc->drmmode->sw_cursor = TRUE;
+}
+
+if (ret)
 /* fallback to swcursor */
 return FALSE;
-}
 return TRUE;
 }
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h 
b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 3b0eb2b..f774250 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -92,7 +92,6 @@ typedef struct {
 int dpms_mode;
 struct dumb_bo *cursor_bo;
 Bool cursor_up;
-Bool set_cursor2_failed;
 uint16_t lut_r[256], lut_g[256], lut_b[256];
 
 drmmode_bo rotate_bo;
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH xserver] glamor: Accelerate XYBitmap PutImage

2016-09-30 Thread Keith Packard
Adam Jackson  writes:

> This could probably be made faster if GL exposed an R1 texture format.

The existing core text code emulates R1 textures; it seems like you
could use those programs for this. We could also use that for
PushPixels at some point.

-- 
-keith


signature.asc
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver 1/3] glamor: Accelerate PutImage for XYBitmap format

2016-09-30 Thread Keith Packard
Upload the bitmap and use a program like TE Text program to draw it,
avoiding fallbacks for this case.

Signed-off-by: Keith Packard 
---
 glamor/glamor_image.c | 183 +++---
 glamor/glamor_priv.h  |   3 +
 2 files changed, 176 insertions(+), 10 deletions(-)

diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 3158749..798277b 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -29,8 +29,8 @@
  */
 
 static Bool
-glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-int w, int h, int leftPad, int format, char *bits)
+glamor_put_image_zpixmap_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, 
int y,
+int w, int h, char *bits)
 {
 ScreenPtr screen = drawable->pScreen;
 glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -52,12 +52,6 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int 
depth, int x, int y,
 if (!glamor_pm_is_solid(gc->depth, gc->planemask))
 goto bail;
 
-if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
-format = ZPixmap;
-
-if (format != ZPixmap)
-goto bail;
-
 x += drawable->x;
 y += drawable->y;
 box.x1 = x;
@@ -84,6 +78,165 @@ bail:
 return FALSE;
 }
 
+static const char vs_vars_put_bitmap[] =
+"attribute vec4 primitive;\n"
+"attribute vec2 source;\n"
+"varying vec2 image_pos;\n";
+
+static const char vs_exec_put_bitmap[] =
+"   vec2 pos = primitive.zw * vec2(gl_VertexID&1, 
(gl_VertexID&2)>>1);\n"
+GLAMOR_POS(gl_Position, (primitive.xy + pos))
+"   image_pos = source + pos;\n";
+
+static const char fs_vars_put_bitmap[] =
+"varying vec2 image_pos;\n";
+
+static Bool
+glamor_put_bitmap_use(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void 
*arg)
+{
+if (!glamor_set_solid(pixmap, gc, TRUE, prog->fg_uniform))
+return FALSE;
+glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
+return TRUE;
+}
+
+static const char fs_exec_put_bitmap[] =
+"   ivec2 itile_texture = ivec2(image_pos);\n"
+"   uint x = uint(itile_texture.x & 7);\n"
+"   itile_texture.x >>= 3;\n"
+"   uint texel = texelFetch(font, itile_texture, 0).x;\n"
+"   uint bit = (texel >> x) & uint(1);\n"
+"   if (bit == uint(0))\n"
+"   gl_FragColor = bg;\n"
+"   else\n"
+"   gl_FragColor = fg;\n";
+
+const glamor_facet glamor_facet_put_bitmap = {
+.name = "put_bitmap",
+.version = 130,
+.vs_vars = vs_vars_put_bitmap,
+.vs_exec = vs_exec_put_bitmap,
+.fs_vars = fs_vars_put_bitmap,
+.fs_exec = fs_exec_put_bitmap,
+.locations = glamor_program_location_fg | glamor_program_location_bg | 
glamor_program_location_font,
+.source_name = "source",
+.use = glamor_put_bitmap_use,
+};
+
+/*
+ * Use a program like the terminal emulator text program to fetch single
+ * bits from the source image and expand them to full pixel values.
+ */
+static Bool
+glamor_put_image_xybitmap_gl(DrawablePtr drawable, GCPtr gc, int x, int y,
+ int w, int h, int leftPad, char *bits)
+{
+ScreenPtr screen = drawable->pScreen;
+glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+uint32_t byte_stride = BitmapBytePad(w + leftPad);
+GLuint texture_id;
+glamor_program *prog;
+char *vbo_offset;
+GLshort *v;
+int box_index;
+int off_x, off_y;
+Bool ret = FALSE;
+
+if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+return FALSE;
+
+glamor_make_current(glamor_priv);
+
+prog = &glamor_priv->put_bitmap_prog;
+
+if (prog->failed)
+goto bail;
+
+if (!prog->prog) {
+if (!glamor_build_program(screen, prog, &glamor_facet_put_bitmap, 
NULL, NULL, NULL))
+goto bail;
+}
+
+if (!glamor_use_program(pixmap, gc, prog, NULL))
+goto bail;
+
+glGenTextures(1, &texture_id);
+glActiveTexture(GL_TEXTURE1);
+glBindTexture(GL_TEXTURE_2D, texture_id);
+
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+glamor_priv->suppress_gl_out_of_memory_logging = true;
+glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, byte_stride, h,
+ 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, bits);
+glamor_priv->suppress_gl_out_of_memory_logging = false;
+if (glGetError() == GL_OUT_OF_MEMORY)
+goto bail;
+
+glUniform1i(prog->font_uniform, 1);
+
+/* Set up the vertex buffers for the font and destination */
+
+v = glamor_get_vbo_space(drawable->pScreen, (6 * sizeof (GLshort)), 
&vbo_offset);
+
+glEnableVertexAttribArray(

[PATCH xserver 0/3] glamor: Accelerate XY format images

2016-09-30 Thread Keith Packard
I took Adam's code to speed up XY format bitmaps and generalized that
for XY format pixmaps too; that speeds up small pixmaps by a
bunch. Then I went and wrote some much faster XY bitmap code which
expands the image with the GPU (just like core text). That turns out
to be faster for large images, but slower for small images due to GL
overhead.

On my Haswell laptop running Xephyr with -glamor-skip-present:

1: xy_old
2: xy_new

   1 2 Operation
   -   -
 10900.099900.0 ( 9.165)   PutImage XY 10x10 square 
  1740.0 2160.0 ( 1.241)   PutImage XY 100x100 square 
83.2   90.4 ( 1.087)   PutImage XY 500x500 square 
 11800.0   351000.0 (29.746)   PutImage XYBitmap 10x10 square 
  6280.081600.0 (12.994)   PutImage XYBitmap 100x100 square 
   752.014300.0 (19.016)   PutImage XYBitmap 500x500 square 

I'd like to know why the GPU expansion version has so much GL
overhead; it "should" be faster for everything as it uploads a lot
less data to the GPU. I'd also like to try writing an XYPixmap that
did all of the plane merging in the fragment shader. That "should" be
faster for large images than merging on the CPU. I tried just using my
XYBitmap code in a loop with a rasterop, but that's actually slower
than using the CPU (at least on my machine). Presumably doing 24
texture uploads isn't all that fast?

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver 2/3] glamor: Accelerate up XY pixmap putimage a little

2016-09-30 Thread Keith Packard
Convert the image to a temporary CPU pixmap, then copy that to the
destination. This is a lot faster for small images, and not any slower
for large images.

Signed-off-by: Keith Packard 
---
 glamor/glamor_image.c | 48 
 1 file changed, 48 insertions(+)

diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 798277b..47968e2 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -237,6 +237,52 @@ bail:
 return ret;
 }
 
+/*
+ * Create a temporary in-memory pixmap, put the image there then copy
+ * to the destination.
+ */
+
+static Bool
+glamor_put_image_xy_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+   int w, int h, int leftPad, int format, char *bits)
+{
+PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ScreenPtr   screen = drawable->pScreen;
+PixmapPtr   temp_pixmap = NULL;
+DrawablePtr temp_drawable;
+GCPtr   temp_gc;
+Boolret = FALSE;
+ChangeGCVal gcv[3];
+
+if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+return FALSE;
+
+temp_pixmap = (*screen->CreatePixmap)(screen, w, h, drawable->depth, 
GLAMOR_CREATE_PIXMAP_CPU);
+if (!temp_pixmap)
+goto bail;
+temp_drawable = &temp_pixmap->drawable;
+temp_gc = GetScratchGC(temp_drawable->depth, screen);
+if (!temp_gc)
+goto bail_pixmap;
+
+/* copy mode for the first plane to clear all of the other bits */
+gcv[0].val = GXcopy;
+gcv[1].val = gc->fgPixel;
+gcv[2].val = gc->bgPixel;
+ChangeGC(NullClient, temp_gc, GCFunction|GCForeground|GCBackground, gcv);
+ValidateGC(temp_drawable, temp_gc);
+(*temp_gc->ops->PutImage)(temp_drawable, temp_gc, depth, 0, 0, w, h, 
leftPad, format, bits);
+(*gc->ops->CopyArea)(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, 
y);
+ret = TRUE;
+
+FreeScratchGC(temp_gc);
+bail_pixmap:
+(*screen->DestroyPixmap)(temp_pixmap);
+bail:
+return ret;
+}
+
 static void
 glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
   int w, int h, int leftPad, int format, char *bits)
@@ -256,6 +302,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, 
int x, int y,
 return;
 break;
 case XYPixmap:
+if (glamor_put_image_xy_gl(drawable, gc, depth, x, y, w, h, leftPad, 
format, bits))
+return;
 break;
 case XYBitmap:
 if (glamor_put_image_xybitmap_gl(drawable, gc, x, y, w, h, leftPad, 
bits))
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH xserver 3/3] glamor: Switch XY bitmap putimage function for small images

2016-09-30 Thread Keith Packard
Use the glamor_put_image_xy_gl for small images as that is quite a bit
faster.

Signed-off-by: Keith Packard 
---
 glamor/glamor_image.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 47968e2..6a70e6a 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -306,8 +306,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int 
depth, int x, int y,
 return;
 break;
 case XYBitmap:
-if (glamor_put_image_xybitmap_gl(drawable, gc, x, y, w, h, leftPad, 
bits))
-return;
+if (w * h >= 100 * 100) {
+if (glamor_put_image_xybitmap_gl(drawable, gc, x, y, w, h, 
leftPad, bits))
+return;
+} else {
+if (glamor_put_image_xy_gl(drawable, gc, depth, x, y, w, h, 
leftPad, format, bits))
+return;
+}
 break;
 }
 glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, 
bits);
-- 
2.9.3

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel