From 5a2587da8d7b2f705f86ab1ce7e3cda271631e67 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 10 Feb 2017 00:22:03 +0100 Subject: [PATCH 01/33] os/xdmcp: Just send XDMCP keepalive packets once every three minute Backported from X.org: commit db1089eafc1c5371fa0030202de588d2e2b4f8e5 Author: Keith Packard Date: Mon Sep 21 07:16:17 2015 +0100 os/xdmcp: Just send XDMCP keepalive packets once every three minutes There was a complicated scheme to increase the time between keepalives from 3 minutes up to as much as 24 hours in an attempt to reduce network traffic from idle X terminals. X terminals receiving X traffic, or receiving user input would use the 3 minute value; X terminals without any network traffic would use a longer value. However, this was actually broken -- any activity in the X server, either client requests or user input, would end up resetting the keepalive timeout, so a user mashing on the keyboard would never discover that the XDMCP master had disappeared and have the session terminated, which was precisely the design goal of the XDMCP keepalive mechanism. Instead of attempting to fix this, accept the cost of a pair of XDMCP packets once every three minutes and just perform keepalives regularly. This will also make reworking the block and wakeup handler APIs to eliminate select masks easier. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/xdmcp.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/nx-X11/programs/Xserver/os/xdmcp.c b/nx-X11/programs/Xserver/os/xdmcp.c index 83e234b438..c4b71f6ec9 100644 --- a/nx-X11/programs/Xserver/os/xdmcp.c +++ b/nx-X11/programs/Xserver/os/xdmcp.c @@ -88,8 +88,6 @@ static int req_socklen; static CARD32 SessionID; static CARD32 timeOutTime; static int timeOutRtx; -static CARD32 defaultKeepaliveDormancy = XDM_DEF_DORMANCY; -static CARD32 keepaliveDormancy = XDM_DEF_DORMANCY; static CARD16 DisplayNumber; static xdmcp_states XDM_INIT_STATE = XDM_OFF; #ifdef HASXDMAUTH @@ -643,6 +641,7 @@ XdmcpOpenDisplay(int sock) if (state != XDM_AWAIT_MANAGE_RESPONSE) return; state = XDM_RUN_SESSION; + timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000; sessionSocket = sock; } @@ -706,7 +705,6 @@ XdmcpWakeupHandler( void * pReadmask) { fd_set* LastSelectMask = (fd_set*)pReadmask; - fd_set devicesReadable; #ifdef NX_TRANS_SOCKET @@ -731,16 +729,6 @@ XdmcpWakeupHandler( FD_CLR(xdmcpSocket6, LastSelectMask); } #endif - XFD_ANDSET(&devicesReadable, LastSelectMask, &EnabledDevices); - if (XFD_ANYSET(&devicesReadable)) - { - if (state == XDM_AWAIT_USER_INPUT) - restart(); - else if (state == XDM_RUN_SESSION) - keepaliveDormancy = defaultKeepaliveDormancy; - } - if (XFD_ANYSET(&AllClients) && state == XDM_RUN_SESSION) - timeOutTime = GetTimeInMillis() + keepaliveDormancy * 1000; } else if (timeOutTime && (int) (GetTimeInMillis() - timeOutTime) >= 0) { @@ -1428,16 +1416,8 @@ recv_alive_msg (unsigned length) { if (SessionRunning && AliveSessionID == SessionID) { - /* backoff dormancy period */ state = XDM_RUN_SESSION; - if ((GetTimeInMillis() - lastDeviceEventTime.milliseconds) > - keepaliveDormancy * 1000) - { - keepaliveDormancy <<= 1; - if (keepaliveDormancy > XDM_MAX_DORMANCY) - keepaliveDormancy = XDM_MAX_DORMANCY; - } - timeOutTime = GetTimeInMillis() + keepaliveDormancy * 1000; + timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000; } else { From 94d277d136984c9b133e5d041b3105c56c39a34c Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 9 Feb 2017 12:32:16 +0000 Subject: [PATCH 02/33] Xserver/include/list.h: Add list.h from X.org (from X.org commit 63f83d1). --- nx-X11/programs/Xserver/include/Imakefile | 1 + nx-X11/programs/Xserver/include/list.h | 494 ++++++++++++++++++++++ 2 files changed, 495 insertions(+) create mode 100644 nx-X11/programs/Xserver/include/list.h diff --git a/nx-X11/programs/Xserver/include/Imakefile b/nx-X11/programs/Xserver/include/Imakefile index 8c89fbc2b2..d1d7bd651b 100644 --- a/nx-X11/programs/Xserver/include/Imakefile +++ b/nx-X11/programs/Xserver/include/Imakefile @@ -30,6 +30,7 @@ InstallDriverSDKNonExecFile(gcstruct.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(globals.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(input.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(inputstr.h,$(DRIVERSDKINCLUDEDIR)) +InstallDriverSDKNonExecFile(list.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(misc.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(miscstruct.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(opaque.h,$(DRIVERSDKINCLUDEDIR)) diff --git a/nx-X11/programs/Xserver/include/list.h b/nx-X11/programs/Xserver/include/list.h new file mode 100644 index 0000000000..3f0574d432 --- /dev/null +++ b/nx-X11/programs/Xserver/include/list.h @@ -0,0 +1,494 @@ +/* + * Copyright © 2010 Intel Corporation + * Copyright © 2010 Francisco Jerez + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef _XORG_LIST_H_ +#define _XORG_LIST_H_ + +#include /* offsetof() */ + +/** + * @file Classic doubly-link circular list implementation. + * For real usage examples of the linked list, see the file test/list.c + * + * Example: + * We need to keep a list of struct foo in the parent struct bar, i.e. what + * we want is something like this. + * + * struct bar { + * ... + * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{} + * ... + * } + * + * We need one list head in bar and a list element in all list_of_foos (both are of + * data type 'struct xorg_list'). + * + * struct bar { + * ... + * struct xorg_list list_of_foos; + * ... + * } + * + * struct foo { + * ... + * struct xorg_list entry; + * ... + * } + * + * Now we initialize the list head: + * + * struct bar bar; + * ... + * xorg_list_init(&bar.list_of_foos); + * + * Then we create the first element and add it to this list: + * + * struct foo *foo = malloc(...); + * .... + * xorg_list_add(&foo->entry, &bar.list_of_foos); + * + * Repeat the above for each element you want to add to the list. Deleting + * works with the element itself. + * xorg_list_del(&foo->entry); + * free(foo); + * + * Note: calling xorg_list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty + * list again. + * + * Looping through the list requires a 'struct foo' as iterator and the + * name of the field the subnodes use. + * + * struct foo *iterator; + * xorg_list_for_each_entry(iterator, &bar.list_of_foos, entry) { + * if (iterator->something == ...) + * ... + * } + * + * Note: You must not call xorg_list_del() on the iterator if you continue the + * loop. You need to run the safe for-each loop instead: + * + * struct foo *iterator, *next; + * xorg_list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) { + * if (...) + * xorg_list_del(&iterator->entry); + * } + * + */ + +/** + * The linkage struct for list nodes. This struct must be part of your + * to-be-linked struct. struct xorg_list is required for both the head of the + * list and for each list node. + * + * Position and name of the struct xorg_list field is irrelevant. + * There are no requirements that elements of a list are of the same type. + * There are no requirements for a list head, any struct xorg_list can be a list + * head. + */ +struct xorg_list { + struct xorg_list *next, *prev; +}; + +/** + * Initialize the list as an empty list. + * + * Example: + * xorg_list_init(&bar->list_of_foos); + * + * @param list The list to initialize + */ +static inline void +xorg_list_init(struct xorg_list *list) +{ + list->next = list->prev = list; +} + +static inline void +__xorg_list_add(struct xorg_list *entry, + struct xorg_list *prev, struct xorg_list *next) +{ + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; +} + +/** + * Insert a new element after the given list head. The new element does not + * need to be initialised as empty list. + * The list changes from: + * head → some element → ... + * to + * head → new element → older element → ... + * + * Example: + * struct foo *newfoo = malloc(...); + * xorg_list_add(&newfoo->entry, &bar->list_of_foos); + * + * @param entry The new element to prepend to the list. + * @param head The existing list. + */ +static inline void +xorg_list_add(struct xorg_list *entry, struct xorg_list *head) +{ + __xorg_list_add(entry, head, head->next); +} + +/** + * Append a new element to the end of the list given with this list head. + * + * The list changes from: + * head → some element → ... → lastelement + * to + * head → some element → ... → lastelement → new element + * + * Example: + * struct foo *newfoo = malloc(...); + * xorg_list_append(&newfoo->entry, &bar->list_of_foos); + * + * @param entry The new element to prepend to the list. + * @param head The existing list. + */ +static inline void +xorg_list_append(struct xorg_list *entry, struct xorg_list *head) +{ + __xorg_list_add(entry, head->prev, head); +} + +static inline void +__xorg_list_del(struct xorg_list *prev, struct xorg_list *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * Remove the element from the list it is in. Using this function will reset + * the pointers to/from this element so it is removed from the list. It does + * NOT free the element itself or manipulate it otherwise. + * + * Using xorg_list_del on a pure list head (like in the example at the top of + * this file) will NOT remove the first element from + * the list but rather reset the list as empty list. + * + * Example: + * xorg_list_del(&foo->entry); + * + * @param entry The element to remove. + */ +static inline void +xorg_list_del(struct xorg_list *entry) +{ + __xorg_list_del(entry->prev, entry->next); + xorg_list_init(entry); +} + +/** + * Check if the list is empty. + * + * Example: + * xorg_list_is_empty(&bar->list_of_foos); + * + * @return True if the list contains one or more elements or False otherwise. + */ +static inline int +xorg_list_is_empty(struct xorg_list *head) +{ + return head->next == head; +} + +/** + * Returns a pointer to the container of this list element. + * + * Example: + * struct foo* f; + * f = container_of(&foo->entry, struct foo, entry); + * assert(f == foo); + * + * @param ptr Pointer to the struct xorg_list. + * @param type Data type of the list element. + * @param member Member name of the struct xorg_list field in the list element. + * @return A pointer to the data struct containing the list head. + */ +#ifndef container_of +#define container_of(ptr, type, member) \ + (type *)((char *)(ptr) - offsetof(type, member)) +#endif + +/** + * Alias of container_of + */ +#define xorg_list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * Retrieve the first list entry for the given list pointer. + * + * Example: + * struct foo *first; + * first = xorg_list_first_entry(&bar->list_of_foos, struct foo, list_of_foos); + * + * @param ptr The list head + * @param type Data type of the list element to retrieve + * @param member Member name of the struct xorg_list field in the list element. + * @return A pointer to the first list element. + */ +#define xorg_list_first_entry(ptr, type, member) \ + xorg_list_entry((ptr)->next, type, member) + +/** + * Retrieve the last list entry for the given listpointer. + * + * Example: + * struct foo *first; + * first = xorg_list_last_entry(&bar->list_of_foos, struct foo, list_of_foos); + * + * @param ptr The list head + * @param type Data type of the list element to retrieve + * @param member Member name of the struct xorg_list field in the list element. + * @return A pointer to the last list element. + */ +#define xorg_list_last_entry(ptr, type, member) \ + xorg_list_entry((ptr)->prev, type, member) + +#ifdef HAVE_TYPEOF +#define __container_of(ptr, sample, member) \ + container_of(ptr, typeof(*sample), member) +#else +/* This implementation of __container_of has undefined behavior according + * to the C standard, but it works in many cases. If your compiler doesn't + * support typeof() and fails with this implementation, please try a newer + * compiler. + */ +#define __container_of(ptr, sample, member) \ + (void *)((char *)(ptr) \ + - ((char *)&(sample)->member - (char *)(sample))) +#endif + +/** + * Loop through the list given by head and set pos to struct in the list. + * + * Example: + * struct foo *iterator; + * xorg_list_for_each_entry(iterator, &bar->list_of_foos, entry) { + * [modify iterator] + * } + * + * This macro is not safe for node deletion. Use xorg_list_for_each_entry_safe + * instead. + * + * @param pos Iterator variable of the type of the list elements. + * @param head List head + * @param member Member name of the struct xorg_list in the list elements. + * + */ +#define xorg_list_for_each_entry(pos, head, member) \ + for (pos = NULL, \ + pos = __container_of((head)->next, pos, member); \ + &pos->member != (head); \ + pos = __container_of(pos->member.next, pos, member)) + +/** + * Loop through the list, keeping a backup pointer to the element. This + * macro allows for the deletion of a list element while looping through the + * list. + * + * See xorg_list_for_each_entry for more details. + */ +#define xorg_list_for_each_entry_safe(pos, tmp, head, member) \ + for (pos = NULL, \ + pos = __container_of((head)->next, pos, member), \ + tmp = __container_of(pos->member.next, pos, member); \ + &pos->member != (head); \ + pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) + +/* NULL-Terminated List Interface + * + * The interface below does _not_ use the struct xorg_list as described above. + * It is mainly for legacy structures that cannot easily be switched to + * struct xorg_list. + * + * This interface is for structs like + * struct foo { + * [...] + * struct foo *next; + * [...] + * }; + * + * The position and field name of "next" are arbitrary. + */ + +/** + * Init the element as null-terminated list. + * + * Example: + * struct foo *list = malloc(); + * nt_list_init(list, next); + * + * @param list The list element that will be the start of the list + * @param member Member name of the field pointing to next struct + */ +#define nt_list_init(_list, _member) \ + (_list)->_member = NULL + +/** + * Returns the next element in the list or NULL on termination. + * + * Example: + * struct foo *element = list; + * while ((element = nt_list_next(element, next)) { } + * + * This macro is not safe for node deletion. Use nt_list_for_each_entry_safe + * instead. + * + * @param list The list or current element. + * @param member Member name of the field pointing to next struct. + */ +#define nt_list_next(_list, _member) \ + (_list)->_member + +/** + * Iterate through each element in the list. + * + * Example: + * struct foo *iterator; + * nt_list_for_each_entry(iterator, list, next) { + * [modify iterator] + * } + * + * @param entry Assigned to the current list element + * @param list The list to iterate through. + * @param member Member name of the field pointing to next struct. + */ +#define nt_list_for_each_entry(_entry, _list, _member) \ + for (_entry = _list; _entry; _entry = (_entry)->_member) + +/** + * Iterate through each element in the list, keeping a backup pointer to the + * element. This macro allows for the deletion of a list element while + * looping through the list. + * + * See nt_list_for_each_entry for more details. + * + * @param entry Assigned to the current list element + * @param tmp The pointer to the next element + * @param list The list to iterate through. + * @param member Member name of the field pointing to next struct. + */ +#define nt_list_for_each_entry_safe(_entry, _tmp, _list, _member) \ + for (_entry = _list, _tmp = (_entry) ? (_entry)->_member : NULL;\ + _entry; \ + _entry = _tmp, _tmp = (_tmp) ? (_tmp)->_member: NULL) + +/** + * Append the element to the end of the list. This macro may be used to + * merge two lists. + * + * Example: + * struct foo *elem = malloc(...); + * nt_list_init(elem, next) + * nt_list_append(elem, list, struct foo, next); + * + * Resulting list order: + * list_item_0 -> list_item_1 -> ... -> elem_item_0 -> elem_item_1 ... + * + * @param entry An entry (or list) to append to the list + * @param list The list to append to. This list must be a valid list, not + * NULL. + * @param type The list type + * @param member Member name of the field pointing to next struct + */ +#define nt_list_append(_entry, _list, _type, _member) \ + do { \ + _type *__iterator = _list; \ + while (__iterator->_member) { __iterator = __iterator->_member;}\ + __iterator->_member = _entry; \ + } while (0) + +/** + * Insert the element at the next position in the list. This macro may be + * used to insert a list into a list. + * + * struct foo *elem = malloc(...); + * nt_list_init(elem, next) + * nt_list_insert(elem, list, struct foo, next); + * + * Resulting list order: + * list_item_0 -> elem_item_0 -> elem_item_1 ... -> list_item_1 -> ... + * + * @param entry An entry (or list) to append to the list + * @param list The list to insert to. This list must be a valid list, not + * NULL. + * @param type The list type + * @param member Member name of the field pointing to next struct + */ +#define nt_list_insert(_entry, _list, _type, _member) \ + do { \ + nt_list_append((_list)->_member, _entry, _type, _member); \ + (_list)->_member = _entry; \ + } while (0) + +/** + * Delete the entry from the list by iterating through the list and + * removing any reference from the list to the entry. + * + * Example: + * struct foo *elem = + * nt_list_del(elem, list, struct foo, next); + * + * @param entry The entry to delete from the list. entry is always + * re-initialized as a null-terminated list. + * @param list The list containing the entry, set to the new list without + * the removed entry. + * @param type The list type + * @param member Member name of the field pointing to the next entry + */ +#define nt_list_del(_entry, _list, _type, _member) \ + do { \ + _type *__e = _entry; \ + if (__e == NULL || _list == NULL) break; \ + if ((_list) == __e) { \ + _list = __e->_member; \ + } else { \ + _type *__prev = _list; \ + while (__prev->_member && __prev->_member != __e) \ + __prev = nt_list_next(__prev, _member); \ + if (__prev->_member) \ + __prev->_member = __e->_member; \ + } \ + nt_list_init(__e, _member); \ + } while(0) + +/** + * DO NOT USE THIS. + * This is a remainder of the xfree86 DDX attempt of having a set of generic + * list functions. Unfortunately, the xf86OptionRec uses it and we can't + * easily get rid of it. Do not use for new code. + */ +typedef struct generic_list_rec { + void *next; +} GenericListRec, *GenericListPtr, *glp; + +#endif From cd728ffb7730b19741756614b0411a14802b1051 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 9 Feb 2017 13:45:12 +0100 Subject: [PATCH 03/33] os: Add NotifyFd interfaces Backported from X.org: commit 0c41b7af4ab0c8d22b88f201293f59524d1e7317 Author: Keith Packard Date: Wed Nov 11 22:02:02 2015 -0800 os: Add NotifyFd interfaces This provides a callback-based interface to monitor file descriptors beyond the usual client and device interfaces. Modules within the server using file descriptors for reading and/or writing can call Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data); mask can be any combination of X_NOTIFY_READ and X_NOTIFY_WRITE. When 'fd' becomes readable or writable, the notify_fd function will be called with the 'fd', the ready conditions and 'data' values as arguments, When the module no longer needs to monitor the fd, it will call void RemoveNotifyFd(int fd); RemoveNotifyFd may be called from the notify function. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/os.h | 13 ++++ nx-X11/programs/Xserver/os/WaitFor.c | 5 ++ nx-X11/programs/Xserver/os/connection.c | 94 +++++++++++++++++++++++++ nx-X11/programs/Xserver/os/osdep.h | 5 ++ nx-X11/programs/Xserver/os/osinit.c | 1 + 5 files changed, 118 insertions(+) diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index 0fd687d183..dfcc639d33 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -147,6 +147,19 @@ extern void AddEnabledDevice(int /*fd*/); extern void RemoveEnabledDevice(int /*fd*/); +typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data); + +#define X_NOTIFY_NONE 0 +#define X_NOTIFY_READ 1 +#define X_NOTIFY_WRITE 2 + +extern Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data); + +static inline void RemoveNotifyFd(int fd) +{ + (void) SetNotifyFd(fd, NULL, X_NOTIFY_NONE, NULL); +} + extern void OnlyListenToOneClient(ClientPtr /*client*/); extern void ListenToAllClients(void); diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index 0ecca8b7ab..19a1b98091 100644 --- a/nx-X11/programs/Xserver/os/WaitFor.c +++ b/nx-X11/programs/Xserver/os/WaitFor.c @@ -504,6 +504,11 @@ WaitForSomething(int *pClientsReady) if (XFD_ANYSET(&tmp_set)) QueueWorkProc(EstablishNewConnections, NULL, (void *)&LastSelectMask); + + XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds); + if (XFD_ANYSET(&tmp_set)) + HandleNotifyFds(); + #ifdef DPMSExtension if (XFD_ANYSET (&devicesReadable) && (DPMSPowerLevel != DPMSModeOn)) DPMSSet(DPMSModeOn); diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 458daab540..23df49883c 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -108,6 +108,7 @@ SOFTWARE. #include #include "opaque.h" #include "dixstruct.h" +#include "list.h" #ifdef XCSECURITY #define _SECURITY_SERVER #include @@ -123,6 +124,7 @@ int lastfdesc; /* maximum file descriptor */ fd_set WellKnownConnections; /* Listener mask */ fd_set EnabledDevices; /* mask for input devices that are on */ +fd_set NotifyReadFds; /* mask for other file descriptors */ fd_set AllSockets; /* select on this */ fd_set AllClients; /* available clients */ fd_set LastSelectMask; /* mask returned from last select call */ @@ -1013,6 +1015,98 @@ RemoveEnabledDevice(int fd) FD_CLR(fd, &SavedAllSockets); } +struct notify_fd { + struct xorg_list list; + int fd; + int mask; + NotifyFdProcPtr notify; + void *data; +}; + +static struct xorg_list notify_fds; + +void +InitNotifyFds(void) +{ + struct notify_fd *s, *next; + static int been_here; + + if (been_here) + xorg_list_for_each_entry_safe(s, next, ¬ify_fds, list) + RemoveNotifyFd(s->fd); + + xorg_list_init(¬ify_fds); + been_here = 1; +} + +/***************** + * SetNotifyFd + * Registers a callback to be invoked when the specified + * file descriptor becomes readable. + *****************/ + +Bool +SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) +{ + struct notify_fd *n; + int changes; + + xorg_list_for_each_entry(n, ¬ify_fds, list) + if (n->fd == fd) + break; + + if (&n->list == ¬ify_fds) { + if (mask == 0) + return TRUE; + + n = calloc(1, sizeof (struct notify_fd)); + if (!n) + return FALSE; + n->fd = fd; + xorg_list_add(&n->list, ¬ify_fds); + } + + changes = n->mask ^ mask; + + if (changes & X_NOTIFY_READ) { + if (mask & X_NOTIFY_READ) { + FD_SET(fd, &NotifyReadFds); + AddGeneralSocket(fd); + } else { + RemoveGeneralSocket(fd); + FD_CLR(fd, &NotifyReadFds); + } + } + if (mask == 0) { + xorg_list_del(&n->list); + free(n); + } else { + n->mask = mask; + n->data = data; + n->notify = notify; + } + + return TRUE; +} + +/***************** + * HandlNotifyFds + * A WorkProc to be called when any of the registered + * file descriptors are readable. + *****************/ + +void +HandleNotifyFds(void) +{ + struct notify_fd *s, *next; + + xorg_list_for_each_entry_safe(s, next, ¬ify_fds, list) { + if (FD_ISSET(s->fd, &LastSelectMask)) { + s->notify(s->fd, X_NOTIFY_READ, s->data); + } + } +} + /***************** * OnlyListenToOneClient: * Only accept requests from one client. Continue to handle new diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index f0e8b707bc..dce44e612e 100644 --- a/nx-X11/programs/Xserver/os/osdep.h +++ b/nx-X11/programs/Xserver/os/osdep.h @@ -188,6 +188,10 @@ extern void FreeOsBuffers( OsCommPtr /*oc*/ ); +extern void InitNotifyFds(void); + +extern void HandleNotifyFds(void); + #include "dix.h" extern ConnectionInputPtr AllocateInputBuffer(void); @@ -199,6 +203,7 @@ extern fd_set AllClients; extern fd_set LastSelectMask; extern fd_set WellKnownConnections; extern fd_set EnabledDevices; +extern fd_set NotifyReadFds; extern fd_set ClientsWithInput; extern fd_set ClientsWriteBlocked; extern fd_set OutputPending; diff --git a/nx-X11/programs/Xserver/os/osinit.c b/nx-X11/programs/Xserver/os/osinit.c index adafa3cf4a..e1986a5772 100644 --- a/nx-X11/programs/Xserver/os/osinit.c +++ b/nx-X11/programs/Xserver/os/osinit.c @@ -203,6 +203,7 @@ OsInit(void) #endif been_here = TRUE; } + InitNotifyFds(); TimerInit(); #ifdef DDXOSINIT OsVendorInit(); From f6a4bf26e0fbb40283e165850a9e22572f51bb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Thu, 9 Feb 2017 21:28:12 +0000 Subject: [PATCH 04/33] Move the code for resetting the DPMS mode in response to input events, from WaitForSomething to mieqProcessInputEvents. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backported from X.org: commit 3b5b7ef5c2ab1d196806f6359e0972fd78d204dd Author: Fredrik Höglund Date: Wed Jan 3 21:05:35 2007 +0100 Move the code for resetting the DPMS mode in response to input events, from WaitForSomething to mieqProcessInputEvents. mieqProcessInputEvents already handles resetting the screen saver. Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/mi/mieq.c | 14 ++++++++++++++ nx-X11/programs/Xserver/os/WaitFor.c | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/nx-X11/programs/Xserver/mi/mieq.c b/nx-X11/programs/Xserver/mi/mieq.c index b5d9baa316..fefb222c4b 100644 --- a/nx-X11/programs/Xserver/mi/mieq.c +++ b/nx-X11/programs/Xserver/mi/mieq.c @@ -43,6 +43,12 @@ in this Software without prior written authorization from The Open Group. # include "mi.h" # include "scrnintstr.h" +#ifdef DPMSExtension +# include "dpmsproc.h" +# define DPMS_SERVER +# include +#endif + #define QUEUE_SIZE 256 typedef struct _Event { @@ -151,6 +157,14 @@ void mieqProcessInputEvents () if (screenIsSaved == SCREEN_SAVER_ON) SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset); +#ifdef DPMSExtension + else if (DPMSPowerLevel != DPMSModeOn) + SetScreenSaverTimer(); + + if (DPMSPowerLevel != DPMSModeOn) + DPMSSet(DPMSModeOn); +#endif + e = &miEventQueue.events[miEventQueue.head]; /* * Assumption - screen switching can only occur on motion events diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index 19a1b98091..d94ada1d5c 100644 --- a/nx-X11/programs/Xserver/os/WaitFor.c +++ b/nx-X11/programs/Xserver/os/WaitFor.c @@ -509,10 +509,6 @@ WaitForSomething(int *pClientsReady) if (XFD_ANYSET(&tmp_set)) HandleNotifyFds(); -#ifdef DPMSExtension - if (XFD_ANYSET (&devicesReadable) && (DPMSPowerLevel != DPMSModeOn)) - DPMSSet(DPMSModeOn); -#endif if (XFD_ANYSET (&devicesReadable) || XFD_ANYSET (&clientsReadable)) break; #ifdef WIN32 From 56a5b9111362d313ef3f28eccdde9b74d58057cd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 9 Feb 2017 23:33:44 +0000 Subject: [PATCH 05/33] os: Implement support for NotifyFd X_NOTIFY_WRITE and removal of AddEnabledDevices/RemoveEnabledDevices Backported from X.org: commit be5a513fee6cbf29ef7570e57eb0436d70fbd88c Author: Keith Packard Date: Mon Dec 7 15:12:14 2015 -0800 Remove AddEnabledDevice and AddGeneralSocket APIs All uses of these interfaces should instead be using the NotifyFd API instead. Signed-off-by: Keith Packard Reviewed-by: Adam Jackson commit 4020aacd1fc5b9c63369f011aeb9120af9c55218 Author: Keith Packard Date: Wed Nov 11 22:02:03 2015 -0800 os: Implement support for NotifyFd X_NOTIFY_WRITE This adds the ability to be notified when a file descriptor is available for writing. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/os.h | 4 -- nx-X11/programs/Xserver/os/WaitFor.c | 35 +++++++----- nx-X11/programs/Xserver/os/connection.c | 72 +++++++++++++------------ nx-X11/programs/Xserver/os/io.c | 9 ++-- nx-X11/programs/Xserver/os/osdep.h | 5 +- 5 files changed, 69 insertions(+), 56 deletions(-) diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index dfcc639d33..99003922fa 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -143,10 +143,6 @@ extern void CheckConnections(void); extern void CloseDownConnection(ClientPtr /*client*/); -extern void AddEnabledDevice(int /*fd*/); - -extern void RemoveEnabledDevice(int /*fd*/); - typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data); #define X_NOTIFY_NONE 0 diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index d94ada1d5c..3ac2e1c7e7 100644 --- a/nx-X11/programs/Xserver/os/WaitFor.c +++ b/nx-X11/programs/Xserver/os/WaitFor.c @@ -188,9 +188,9 @@ WaitForSomething(int *pClientsReady) int curclient; int selecterr; int nready; - fd_set devicesReadable; CARD32 now = 0; Bool someReady = FALSE; + Bool someNotifyWriteReady = FALSE; #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) fprintf(stderr, "WaitForSomething: Got called.\n"); @@ -338,7 +338,7 @@ WaitForSomething(int *pClientsReady) if (dispatchException) i = -1; #endif - else if (AnyClientsWriteBlocked) + else if (AnyWritesPending) { #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) if (wt == NULL) @@ -353,8 +353,9 @@ WaitForSomething(int *pClientsReady) wt -> tv_sec, wt -> tv_usec); } #endif - XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable); - i = Select (MaxClients, &LastSelectMask, &clientsWritable, NULL, wt); + XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask); + XFD_ORSET(&LastSelectWriteMask, &NotifyWriteFds, &LastSelectWriteMask); + i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, NULL, wt); } else { @@ -489,16 +490,22 @@ WaitForSomething(int *pClientsReady) } if (someReady) XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask); - if (AnyClientsWriteBlocked && XFD_ANYSET (&clientsWritable)) - { - NewOutputPending = TRUE; - XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending); - XFD_UNSET(&ClientsWriteBlocked, &clientsWritable); - if (! XFD_ANYSET(&ClientsWriteBlocked)) - AnyClientsWriteBlocked = FALSE; + if (AnyWritesPending) { + XFD_ANDSET(&clientsWritable, &LastSelectWriteMask, &ClientsWriteBlocked); + if (XFD_ANYSET(&clientsWritable)) { + NewOutputPending = TRUE; + XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending); + XFD_UNSET(&ClientsWriteBlocked, &clientsWritable); + if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) + AnyWritesPending = FALSE; + } + if (NumNotifyWriteFd != 0) { + XFD_ANDSET(&tmp_set, &LastSelectWriteMask, &NotifyWriteFds); + if (XFD_ANYSET(&tmp_set)) + someNotifyWriteReady = TRUE; + } } - XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices); XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections); if (XFD_ANYSET(&tmp_set)) @@ -506,10 +513,10 @@ WaitForSomething(int *pClientsReady) (void *)&LastSelectMask); XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds); - if (XFD_ANYSET(&tmp_set)) + if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady) HandleNotifyFds(); - if (XFD_ANYSET (&devicesReadable) || XFD_ANYSET (&clientsReadable)) + if (XFD_ANYSET (&clientsReadable)) break; #ifdef WIN32 /* Windows keyboard and mouse events are added to the input queue diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 23df49883c..966fe208db 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -48,8 +48,8 @@ SOFTWARE. * Stuff to create connections --- OS dependent * * EstablishNewConnections, CreateWellKnownSockets, ResetWellKnownSockets, - * CloseDownConnection, CheckConnections, AddEnabledDevice, - * RemoveEnabledDevice, OnlyListToOneClient, + * CloseDownConnection, CheckConnections, + * OnlyListToOneClient, * ListenToAllClients, * * (WaitForSomething is in its own file) @@ -123,18 +123,19 @@ SOFTWARE. int lastfdesc; /* maximum file descriptor */ fd_set WellKnownConnections; /* Listener mask */ -fd_set EnabledDevices; /* mask for input devices that are on */ fd_set NotifyReadFds; /* mask for other file descriptors */ +fd_set NotifyWriteFds; /* mask for other write file descriptors */ fd_set AllSockets; /* select on this */ fd_set AllClients; /* available clients */ fd_set LastSelectMask; /* mask returned from last select call */ +fd_set LastSelectWriteMask; /* mask returned from last select call */ fd_set ClientsWithInput; /* clients with FULL requests in buffer */ fd_set ClientsWriteBlocked; /* clients who cannot receive output */ fd_set OutputPending; /* clients with reply/event data ready to go */ int MaxClients = 0; +int NumNotifyWriteFd; /* Number of NotifyFd members with write set */ Bool NewOutputPending; /* not yet attempted to write some new output */ -Bool AnyClientsWriteBlocked; /* true if some client blocked on write */ - +Bool AnyWritesPending; /* true if some client blocked on write or NotifyFd with write */ Bool RunFromSmartParent; /* send SIGUSR1 to parent process */ Bool PartialNetwork; /* continue even if unable to bind all addrs */ static Pid_t ParentProcess; @@ -913,8 +914,8 @@ CloseDownFileDescriptor(OsCommPtr oc) FD_CLR(connection, &SavedClientsWithInput); } FD_CLR(connection, &ClientsWriteBlocked); - if (!XFD_ANYSET(&ClientsWriteBlocked)) - AnyClientsWriteBlocked = FALSE; + if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) + AnyWritesPending = FALSE; FD_CLR(connection, &OutputPending); } @@ -997,24 +998,6 @@ CloseDownConnection(ClientPtr client) AuditF("client %d disconnected\n", client->index); } -void -AddEnabledDevice(int fd) -{ - FD_SET(fd, &EnabledDevices); - FD_SET(fd, &AllSockets); - if (GrabInProgress) - FD_SET(fd, &SavedAllSockets); -} - -void -RemoveEnabledDevice(int fd) -{ - FD_CLR(fd, &EnabledDevices); - FD_CLR(fd, &AllSockets); - if (GrabInProgress) - FD_CLR(fd, &SavedAllSockets); -} - struct notify_fd { struct xorg_list list; int fd; @@ -1036,6 +1019,7 @@ InitNotifyFds(void) RemoveNotifyFd(s->fd); xorg_list_init(¬ify_fds); + NumNotifyWriteFd = 0; been_here = 1; } @@ -1071,12 +1055,30 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (changes & X_NOTIFY_READ) { if (mask & X_NOTIFY_READ) { FD_SET(fd, &NotifyReadFds); - AddGeneralSocket(fd); + FD_SET(fd, &AllSockets); + if (GrabInProgress) + FD_SET(fd, &SavedAllSockets); } else { - RemoveGeneralSocket(fd); + FD_CLR(fd, &AllSockets); + if (GrabInProgress) + FD_CLR(fd, &SavedAllSockets); FD_CLR(fd, &NotifyReadFds); } } + + if (changes & X_NOTIFY_WRITE) { + if (mask & X_NOTIFY_WRITE) { + FD_SET(fd, &NotifyWriteFds); + if (!NumNotifyWriteFd++) + AnyWritesPending = TRUE; + } else { + FD_CLR(fd, &NotifyWriteFds); + if (!--NumNotifyWriteFd) + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyWritesPending = FALSE; + } + } + if (mask == 0) { xorg_list_del(&n->list); free(n); @@ -1098,12 +1100,16 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) void HandleNotifyFds(void) { - struct notify_fd *s, *next; - - xorg_list_for_each_entry_safe(s, next, ¬ify_fds, list) { - if (FD_ISSET(s->fd, &LastSelectMask)) { - s->notify(s->fd, X_NOTIFY_READ, s->data); - } + struct notify_fd *n, *next; + + xorg_list_for_each_entry_safe(n, next, ¬ify_fds, list) { + int ready = 0; + if ((n->mask & X_NOTIFY_READ) && FD_ISSET(n->fd, &LastSelectMask)) + ready |= X_NOTIFY_READ; + if ((n->mask & X_NOTIFY_WRITE) & FD_ISSET(n->fd, &LastSelectWriteMask)) + ready |= X_NOTIFY_WRITE; + if (ready != 0) + n->notify(n->fd, ready, n->data); } } diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index 87739cfb15..92a3f04763 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -1062,7 +1062,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) and not ready to accept more. Make a note of it and buffer the rest. */ FD_SET(connection, &ClientsWriteBlocked); - AnyClientsWriteBlocked = TRUE; + AnyWritesPending = TRUE; if (written < oco->count) { @@ -1134,11 +1134,12 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) /* everything was flushed out */ oco->count = 0; /* check to see if this client was write blocked */ - if (AnyClientsWriteBlocked) + if (AnyWritesPending) { FD_CLR(oc->fd, &ClientsWriteBlocked); - if (! XFD_ANYSET(&ClientsWriteBlocked)) - AnyClientsWriteBlocked = FALSE; + if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) + AnyWritesPending = FALSE; + } if (oco->size > BUFWATERMARK) { diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index dce44e612e..6ac9d860e7 100644 --- a/nx-X11/programs/Xserver/os/osdep.h +++ b/nx-X11/programs/Xserver/os/osdep.h @@ -201,9 +201,11 @@ extern ConnectionOutputPtr AllocateOutputBuffer(void); extern fd_set AllSockets; extern fd_set AllClients; extern fd_set LastSelectMask; +extern fd_set LastSelectWriteMask; extern fd_set WellKnownConnections; extern fd_set EnabledDevices; extern fd_set NotifyReadFds; +extern fd_set NotifyWriteFds; extern fd_set ClientsWithInput; extern fd_set ClientsWriteBlocked; extern fd_set OutputPending; @@ -218,7 +220,8 @@ extern void ClearConnectionTranslation(); #endif extern Bool NewOutputPending; -extern Bool AnyClientsWriteBlocked; +extern Bool AnyWritesPending; +extern Bool NumNotifyWriteFd; extern Bool CriticalOutputPending; extern int timesThisConnection; From 1c438c1b2961fa1f700e1e1e79d5f53b412acbbd Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 9 Feb 2017 23:35:00 +0000 Subject: [PATCH 06/33] nxagent: Use SetNotifyFd to receive events. Inspired by X.org commit: commit 55c2e1a3aa587c58a74066724e11e30b3df267b8 Author: Keith Packard Date: Mon Dec 7 15:11:33 2015 -0800 xnest: Use SetNotifyFd to receive events Signed-off-by: Keith Packard Reviewed-by: Adam Jackson --- nx-X11/programs/Xserver/hw/nxagent/Display.c | 4 ++-- nx-X11/programs/Xserver/hw/nxagent/Init.c | 7 +++++++ nx-X11/programs/Xserver/hw/nxagent/Init.h | 2 ++ nx-X11/programs/Xserver/hw/nxagent/Screen.c | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c index 599b335f66..c683751f6a 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Display.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c @@ -2877,7 +2877,7 @@ void nxagentAddXConnection() "to the device set.\n", nxagentXConnectionNumber); #endif - AddEnabledDevice(nxagentXConnectionNumber); + SetNotifyFd(XConnectionNumber(nxagentDisplay), nxagentNotifyConnection, X_NOTIFY_READ, NULL); } void nxagentRemoveXConnection() @@ -2887,7 +2887,7 @@ void nxagentRemoveXConnection() "from the device set.\n", nxagentXConnectionNumber); #endif - RemoveEnabledDevice(nxagentXConnectionNumber); + RemoveNotifyFd(nxagentXConnectionNumber); } /* diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c index 218766e064..f15f2cb0a6 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Init.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c @@ -58,6 +58,7 @@ is" without express or implied warranty. #include "Pointer.h" #include "Keyboard.h" #include "Handlers.h" +#include "Events.h" #include "Init.h" #include "Args.h" #include "Client.h" @@ -407,6 +408,12 @@ FIXME: These variables, if not removed at all because have probably blackRoot = TRUE; } +void +nxagentNotifyConnection(int fd, int ready, void *data) +{ + nxagentDispatchEvents(NULL); +} + void InitInput(argc, argv) int argc; char *argv[]; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h index 29b1100e79..34a17067fd 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Init.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h @@ -49,4 +49,6 @@ extern int nxagentX2go; extern ServerGrabInfoRec nxagentGrabServerInfo; +void nxagentNotifyConnection(int fd, int ready, void *data); + #endif /* __Init_H__ */ diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 3039f41392..01d8c1fc73 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -2781,7 +2781,7 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin) "to the device set.\n", fd); #endif - AddEnabledDevice(nxagentShadowXConnectionNumber); + SetNotifyFd(nxagentShadowXConnectionNumber, nxagentNotifyConnection, X_NOTIFY_READ, NULL); accessPixmapID = FakeClientID(serverClient -> index); From 2afe0957dbe1c26a049d1e29d951a818051e292b Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 24 Feb 2017 13:03:30 +0000 Subject: [PATCH 07/33] os: Initialize NotifyFds earlier in startup Backported from X.org: commit ce6546337487c052b5dd3c04d3d8d4b09d691c3d Author: Keith Packard Date: Tue May 31 09:38:17 2016 -0700 os: Initialize NotifyFds earlier in startup If the server calls AbortServer during the first-time initialization (which can happen if you start the server on an already using DISPLAY), then the dbus code will shut down and call the notify fd interface. If the notify fd list hasn't been initialized, the server will crash. Signed-off-by: Keith Packard Reviewed-by: Peter Hutterer Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/osinit.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nx-X11/programs/Xserver/os/osinit.c b/nx-X11/programs/Xserver/os/osinit.c index e1986a5772..08fbb8c897 100644 --- a/nx-X11/programs/Xserver/os/osinit.c +++ b/nx-X11/programs/Xserver/os/osinit.c @@ -101,10 +101,15 @@ OsInit(void) #endif if (!been_here) { + + InitNotifyFds(); + #if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__) fclose(stdin); fclose(stdout); #endif + + /* * If a write of zero bytes to stderr returns non-zero, i.e. -1, * then writing to stderr failed, and we'll write somewhere else @@ -203,7 +208,6 @@ OsInit(void) #endif been_here = TRUE; } - InitNotifyFds(); TimerInit(); #ifdef DDXOSINIT OsVendorInit(); From af514300dab78e2575f4e2a0ce733fa4072506e9 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Fri, 10 Mar 2017 12:02:11 +0100 Subject: [PATCH 08/33] randr: Do not update ConnectionInfo if NULL commit 941aeb3b92e644923bd112eef8023f033a140ee6 Author: Olivier Fourdan Date: Fri May 13 08:58:58 2016 +0200 randr: Do not update ConnectionInfo if NULL RRScreenSizeNotify() will update the connection information block, but if this occurs during initialization before ConnectionInfo is even initialized, this will lead to a crash. Simply check for ConnectionInfo prior to update it to avoid the crash. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95337 Reviewed-by: Adam Jackson Signed-off-by: Olivier Fourdan Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/rrscreen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nx-X11/programs/Xserver/randr/rrscreen.c b/nx-X11/programs/Xserver/randr/rrscreen.c index 4f59e9aeac..90371704a6 100644 --- a/nx-X11/programs/Xserver/randr/rrscreen.c +++ b/nx-X11/programs/Xserver/randr/rrscreen.c @@ -66,6 +66,9 @@ RREditConnectionInfo(ScreenPtr pScreen) int screen = 0; int d; + if (ConnectionInfo == NULL) + return; + connSetup = (xConnSetup *) ConnectionInfo; vendor = (char *) connSetup + sizeof(xConnSetup); formats = (xPixmapFormat *) ((char *) vendor + From 2b7d5204a7ab5ee7d53ef1d5f0e16c3cd54e7703 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 10 Mar 2017 13:48:30 +0100 Subject: [PATCH 09/33] xrandrprovider: Do not use separate lists for unbound / source / offload slaves Backported from X.org and not-yet-enabled ABI-wise in NXAGENT_SERVER: commit 5c7af02b103790ac1fb6a71822788892c70290b6 Author: Hans de Goede Date: Fri May 13 15:58:10 2016 +0200 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 Reviewed-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/randr.c | 42 +++++++----------- nx-X11/programs/Xserver/randr/rrcrtc.c | 16 +++++-- nx-X11/programs/Xserver/randr/rrmonitor.c | 21 ++++++--- nx-X11/programs/Xserver/randr/rroutput.c | 8 ++-- nx-X11/programs/Xserver/randr/rrprovider.c | 51 ++++++++-------------- nx-X11/programs/Xserver/randr/rrscreen.c | 12 +++-- 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/nx-X11/programs/Xserver/randr/randr.c b/nx-X11/programs/Xserver/randr/randr.c index e991af3403..f87d518b34 100644 --- a/nx-X11/programs/Xserver/randr/randr.c +++ b/nx-X11/programs/Xserver/randr/randr.c @@ -569,7 +569,10 @@ TellChanged(WindowPtr pWin, void *value) } #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) { + if (!iter->is_output_slave) + continue; + pSlaveScrPriv = rrGetScrPriv(iter); for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pSlaveScrPriv->crtcs[i]; @@ -590,7 +593,10 @@ TellChanged(WindowPtr pWin, void *value) } #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) { + if (!iter->is_output_slave) + continue; + pSlaveScrPriv = rrGetScrPriv(iter); for (i = 0; i < pSlaveScrPriv->numOutputs; i++) { RROutputPtr output = pSlaveScrPriv->outputs[i]; @@ -604,17 +610,7 @@ TellChanged(WindowPtr pWin, void *value) #ifndef NXAGENT_SERVER if (pRREvent->mask & RRProviderChangeNotifyMask) { - xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { - pSlaveScrPriv = rrGetScrPriv(iter); - if (pSlaveScrPriv->provider->changed) - RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider); - } - xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { - pSlaveScrPriv = rrGetScrPriv(iter); - if (pSlaveScrPriv->provider->changed) - RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider); - } - xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { + xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) { pSlaveScrPriv = rrGetScrPriv(iter); if (pSlaveScrPriv->provider->changed) RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider); @@ -706,21 +702,15 @@ RRTellChanged(ScreenPtr pScreen) pScrPriv->crtcs[i]->changed = FALSE; #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(iter, &master->output_slave_list, output_head) { - pSlaveScrPriv = rrGetScrPriv(iter); - pSlaveScrPriv->provider->changed = FALSE; - for (i = 0; i < pSlaveScrPriv->numOutputs; i++) - pSlaveScrPriv->outputs[i]->changed = FALSE; - for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) - pSlaveScrPriv->crtcs[i]->changed = FALSE; - } - xorg_list_for_each_entry(iter, &master->offload_slave_list, offload_head) { - pSlaveScrPriv = rrGetScrPriv(iter); - pSlaveScrPriv->provider->changed = FALSE; - } - xorg_list_for_each_entry(iter, &master->unattached_list, unattached_head) { + xorg_list_for_each_entry(iter, &master->slave_list, slave_head) { pSlaveScrPriv = rrGetScrPriv(iter); pSlaveScrPriv->provider->changed = FALSE; + if (iter->is_output_slave) { + for (i = 0; i < pSlaveScrPriv->numOutputs; i++) + pSlaveScrPriv->outputs[i]->changed = FALSE; + for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) + pSlaveScrPriv->crtcs[i]->changed = FALSE; + } } #endif /* !defined(NXAGENT_SERVER) */ diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index 7775747f83..4a460b9742 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -552,8 +552,12 @@ rrCheckPixmapBounding(ScreenPtr pScreen, RegionUnion(&total_region, &total_region, &new_crtc_region); } - xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { + xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) { rrScrPrivPtr slave_priv = rrGetScrPriv(slave); + + if (!slave->is_output_slave) + continue; + for (c = 0; c < slave_priv->numCrtcs; c++) { RRCrtcPtr slave_crtc = slave_priv->crtcs[c]; @@ -1775,7 +1779,10 @@ RRConstrainCursorHarder( return; #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { + xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) { + if (!slave->is_output_slave) + continue; + ret = check_all_screen_crtcs(slave, x, y); if (ret == TRUE) return; @@ -1792,7 +1799,10 @@ RRConstrainCursorHarder( return; #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { + xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) { + if (!slave->is_output_slave) + continue; + ret = constrain_all_screen_crtcs(pDev, slave, x, y); if (ret == TRUE) return; diff --git a/nx-X11/programs/Xserver/randr/rrmonitor.c b/nx-X11/programs/Xserver/randr/rrmonitor.c index e9031a5674..029d9fd61e 100644 --- a/nx-X11/programs/Xserver/randr/rrmonitor.c +++ b/nx-X11/programs/Xserver/randr/rrmonitor.c @@ -208,8 +208,12 @@ RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active) /* Count the number of crtcs in this and any slave screens */ numCrtcs = pScrPriv->numCrtcs; #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) { - rrScrPrivPtr pSlavePriv; + xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) { + rrScrPrivPtr pSlavePriv; + + if (!slave->is_output_slave) + continue; + pSlavePriv = rrGetScrPriv(slave); numCrtcs += pSlavePriv->numCrtcs; } @@ -228,8 +232,12 @@ RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active) } #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) { - rrScrPrivPtr pSlavePriv; + xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) { + rrScrPrivPtr pSlavePriv; + + if (!slave->is_output_slave) + continue; + pSlavePriv = rrGetScrPriv(slave); for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) { if (pSlavePriv->crtcs[sc]->mode != NULL) @@ -483,7 +491,10 @@ RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor) } #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) { + xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) { + if (!slave->is_output_slave) + continue; + if (RRMonitorMatchesOutputName(slave, monitor->name)) { client->errorValue = monitor->name; return BadValue; diff --git a/nx-X11/programs/Xserver/randr/rroutput.c b/nx-X11/programs/Xserver/randr/rroutput.c index 8042b719c4..b8e66e15dd 100644 --- a/nx-X11/programs/Xserver/randr/rroutput.c +++ b/nx-X11/programs/Xserver/randr/rroutput.c @@ -595,10 +595,10 @@ ProcRRSetOutputPrimary(ClientPtr client) #ifndef NXAGENT_SERVER xorg_list_for_each_entry(slave, - &pWin->drawable.pScreen->output_slave_list, - output_head) { - rrScrPrivPtr pSlavePriv; - pSlavePriv = rrGetScrPriv(slave); + &pWin->drawable.pScreen->slave_list, + slave_head) { + if (slave->is_output_slave) + RRSetPrimaryOutput(slave, rrGetScrPriv(slave), output); RRSetPrimaryOutput(slave, pSlavePriv, output); } diff --git a/nx-X11/programs/Xserver/randr/rrprovider.c b/nx-X11/programs/Xserver/randr/rrprovider.c index 1f884a7b2e..e254111818 100644 --- a/nx-X11/programs/Xserver/randr/rrprovider.c +++ b/nx-X11/programs/Xserver/randr/rrprovider.c @@ -83,15 +83,7 @@ ProcRRGetProviders(ClientPtr client) if (pScrPriv->provider) total_providers++; #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { - pScrPriv = rrGetScrPriv(iter); - total_providers += pScrPriv->provider ? 1 : 0; - } - xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { - pScrPriv = rrGetScrPriv(iter); - total_providers += pScrPriv->provider ? 1 : 0; - } - xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { + xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) { pScrPriv = rrGetScrPriv(iter); total_providers += pScrPriv->provider ? 1 : 0; } @@ -129,13 +121,7 @@ ProcRRGetProviders(ClientPtr client) providers = (RRProvider *) extra; ADD_PROVIDER(pScreen); #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { - ADD_PROVIDER(iter); - } - xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { - ADD_PROVIDER(iter); - } - xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { + xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) { ADD_PROVIDER(iter); } #endif @@ -201,13 +187,14 @@ ProcRRGetProviderInfo(ClientPtr client) /* count associated providers */ if (provider->offload_sink) rep.nAssociatedProviders++; - if (provider->output_source) - rep.nAssociatedProviders++; #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) - rep.nAssociatedProviders++; - xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) - rep.nAssociatedProviders++; + if (provider->output_source && + provider->output_source != provider->offload_sink) + rep.nAssociatedProviders++; + xorg_list_for_each_entry(provscreen, &pScreen->slave_list, slave_head) { + if (provscreen->is_output_slave || provscreen->is_offload_slave) + rep.nAssociatedProviders++; + } #endif rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs + @@ -259,22 +246,18 @@ ProcRRGetProviderInfo(ClientPtr client) i++; } #ifndef NXAGENT_SERVER - xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) { - pScrProvPriv = rrGetScrPriv(provscreen); - providers[i] = pScrProvPriv->provider->id; - if (client->swapped) - swapl(&providers[i]); - prov_cap[i] = RR_Capability_SinkOutput; - if (client->swapped) - swapl(&prov_cap[i]); - i++; - } - xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) { + xorg_list_for_each_entry(provscreen, &pScreen->slave_list, slave_head) { + if (!provscreen->is_output_slave && !provscreen->is_offload_slave) + continue; pScrProvPriv = rrGetScrPriv(provscreen); providers[i] = pScrProvPriv->provider->id; if (client->swapped) swapl(&providers[i]); - prov_cap[i] = RR_Capability_SourceOffload; + prov_cap[i] = 0; + if (provscreen->is_output_slave) + prov_cap[i] |= RR_Capability_SinkOutput; + if (provscreen->is_offload_slave) + prov_cap[i] |= RR_Capability_SourceOffload; if (client->swapped) swapl(&prov_cap[i]); i++; diff --git a/nx-X11/programs/Xserver/randr/rrscreen.c b/nx-X11/programs/Xserver/randr/rrscreen.c index 90371704a6..edb4ebf6ec 100644 --- a/nx-X11/programs/Xserver/randr/rrscreen.c +++ b/nx-X11/programs/Xserver/randr/rrscreen.c @@ -432,7 +432,10 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) update_totals(pScreen, pScrPriv); - xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) { + if (!iter->is_output_slave) + continue; + pScrPriv = rrGetScrPriv(iter); if (query) @@ -488,7 +491,10 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) } update_arrays(pScreen, pScrPriv, primary_crtc, has_primary); - xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) { + if (!iter->is_output_slave) + continue; + pScrPriv = rrGetScrPriv(iter); update_arrays(iter, pScrPriv, primary_crtc, has_primary); @@ -549,7 +555,7 @@ rrGetScreenResources(ClientPtr client, Bool query) return BadAlloc; #ifndef NXAGENT_SERVER - if (!xorg_list_is_empty(&pScreen->output_slave_list)) + if (pScreen->output_slaves) return rrGetMultiScreenResources(client, query, pScreen); #endif From 76d5d6434c27a9d5ae22a5ab49335af554b76265 Mon Sep 17 00:00:00 2001 From: Nikhil Mahale Date: Fri, 10 Mar 2017 13:59:13 +0100 Subject: [PATCH 10/33] randr: Adjust master's last set time with slaves commit 15595d29c2c3992f260a3314f26fa691f1e5cec8 Author: Nikhil Mahale Date: Thu May 26 21:50:16 2016 +0530 randr: Adjust master's last set time with slaves In prime configurations master's last set time may not be latest and greatest, adjust it with slaves last set time, pick up greatest one. Otherwise xserver may end with events which has lastSetTime < lastConfigTime even if that's not the case and confuse xrandr client. [hdegoede: rebase on "xrandrprovider: Do not use separate lists for unbound / source / offload slaves"] Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/randr.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nx-X11/programs/Xserver/randr/randr.c b/nx-X11/programs/Xserver/randr/randr.c index f87d518b34..9149c8a560 100644 --- a/nx-X11/programs/Xserver/randr/randr.c +++ b/nx-X11/programs/Xserver/randr/randr.c @@ -683,6 +683,20 @@ RRTellChanged(ScreenPtr pScreen) mastersp = pScrPriv; } +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(iter, &master->slave_list, slave_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + + if (!iter->is_output_slave) + continue; + + if (CompareTimeStamps(mastersp->lastSetTime, + pSlaveScrPriv->lastSetTime) == EARLIER) { + mastersp->lastSetTime = pSlaveScrPriv->lastSetTime; + } + } +#endif + if (mastersp->changed) { UpdateCurrentTimeIf(); if (mastersp->configChanged) { From 63748430bdd87766608b67746a073e8e4d0f1050 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 10 Mar 2017 14:08:45 +0100 Subject: [PATCH 11/33] randr: Fix crtc_bounds when using rotation combined with reflection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backported from X.org: commit 35c4e96ed1d372dd161480be8cddcd2d4549e449 Author: Hans de Goede Date: Mon Sep 12 12:47:59 2016 +0200 randr: Fix crtc_bounds when using rotation combined with reflection Before this commit crtc_bounds() did not take reflection into account, when using reflection with 0 / 180 degree rotation this was not an issue because of the default in the switch-case doing the right thing. But when using 90 / 270 degree rotation we would also end up in the default which is wrong in this case. This would lead to the cursor being constrained to a height x height area of the monitor. This commit masks out the reflection bits for the switch-case, making crtc_bounds return the correct bounds and fixing the problematic cursor constraining. Signed-off-by: Hans de Goede Reviewed-by: Michel Dänzer Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/rrcrtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index 4a460b9742..e997e9d643 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -304,7 +304,7 @@ crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom) *left = crtc->x; *top = crtc->y; - switch (crtc->rotation) { + switch (crtc->rotation & 0xf) { case RR_Rotate_0: case RR_Rotate_180: default: From 64ee3a31c14d1b67f4ce11a1450a0f773c8f9ee4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 10 Mar 2017 14:12:02 +0100 Subject: [PATCH 12/33] randr: rrCheckPixmapBounding: Do not substract crtc non 0 x,y from screen size Backported from X.org (and not-yet-enabled in NXAGENT_SERVER): commit 3b624aa9a9df86dc7d48149e0f18ca223b4355f1 Author: Hans de Goede Date: Tue Nov 22 14:48:14 2016 +0100 randr: rrCheckPixmapBounding: Do not substract crtc non 0 x,y from screen size The purpose of rrCheckPixmapBounding is to make sure that the screen_pixmap is large enough for the slave-output which crtc is being configured. This should include crtc->x and crtc->y, otherwise the crtc might still end up scanning out an area outside of the screen-pixmap. For example: Take a laptop with an external monitor on a slave-output at 1920x1080+0+0 and its internal-screen at 3840x2160+1920+0 and in gnome-settings-daemon move the external monitor to be on the ri ght of the internal screen rather then on the left. First g-s-d will do a RRSetScreenSize to 5760*2160 (which is a nop), then it calls RRSetCrtc to move the slave output to 1920x1080+3840+0, since this is a slave output, rrCheckPixmapBounding gets called, since the 2 crtcs now overlap the code before this commit would shrinks the screen_pixmap to 3180*2160. randr: rrCheckPixmapBounding: Do not substract crtc non 0 x,y from screen size randr: rrCheckPixmapBounding: Do not substract crtc non 0 x,y from screen size The purpose of rrCheckPixmapBounding is to make sure that the screen_pixmap is large enough for the slave-output which crtc is being configured. This should include crtc->x and crtc->y, otherwise the crtc might still end up scanning out an area outside of the screen-pixmap. For example: Take a laptop with an external monitor on a slave-output at 1920x1080+0+0 and its internal-screen at 3840x2160+1920+0 and in gnome-settings-daemon move the external monitor to be on the ri ght of the internal screen rather then on the left. First g-s-d will do a RRSetScreenSize to 5760*2160 (which is a nop), then it calls RRSetCrtc to move the slave output to 1920x1080+3840+0, since this is a slave output, rrCheckPixmapBounding gets called, since the 2 crtcs now overlap the code before this commit would shrinks the screen_pixmap to 3180*2160. Then g-s-d calls RRSetCrtc to move the internal screen to 3180*2160+0+0. And we end up with the slave-output configured to scan-out an area which completely falls outside of the screen-pixmap (and end up with a black display on the external monitor). This commit fixes this by not substracting the x1 and y1 coordinates of the union-ed region when determining the new screen_pixmap size. Cc: Nikhil Mahale Cc: Dave Airlie Signed-off-by: Hans de Goede Reviewed-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/rrcrtc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index e997e9d643..53508c96b3 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -584,8 +584,8 @@ rrCheckPixmapBounding(ScreenPtr pScreen, } newsize = RegionExtents(&total_region); - new_width = newsize->x2 - newsize->x1; - new_height = newsize->y2 - newsize->y1; + new_width = newsize->x2; + new_height = newsize->y2; if (new_width == screen_pixmap->drawable.width && new_height == screen_pixmap->drawable.height) { From 086630fb151caeb3abd691bc167c7ff98373e725 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 10 Mar 2017 14:13:52 +0100 Subject: [PATCH 13/33] randr: rrCheckPixmapBounding: do not shrink the screen_pixmap Backported from X.org (and not-yet-enabled in NXAGENT_SERVER): commit a46afee84d45fbff4e4dad9376afc95bbcc31d7c Author: Hans de Goede Date: Tue Nov 22 14:53:20 2016 +0100 randr: rrCheckPixmapBounding: do not shrink the screen_pixmap The purpose of rrCheckPixmapBounding is to make sure that the screen_pixmap is *large* enough for the slave-output which crtc is being configured. However until now rrCheckPixmapBounding would also shrink the screen_pixmap in certain scenarios leading to various problems. For example: Take a laptop with its internalscreen on a slave-output and currently disabled and an external monitor at 1920x1080+0+0. Now lets say that we want to drive the external monitor at its native resolution of 2560x1440 and have the internal screen mirror the top left part of the external monitor, so we run: $ xrandr --output eDP --mode 1920x1080 --pos 0x0 --output HDMI \ --mode 2560x1440 --pos 0x0 Here xrandr utility first calls RRSetScreenSize to 2560x1440, then it calls RRSetCrtc 1920x1080+0+0 on the eDP, since this is a slave output, rrCheckPixmapBounding gets called and resizes the screen_pixmap to 1920x1080, undoing the RRSetScreenSize. Then RRSetCrtc 2560x1440+0+0 gets called on the HDMI, depending on crtc->transforms this will either result in a BadValue error from ProcRRSetCrtcConfig; or it will succeed, but the monitor ends up running at 2560x1440 while showing a 1920x1080 screen_pixmap + black borders on the right and bottom. Neither of which is what we want. This commit removes the troublesome shrinking behavior, fixing this. Note: 1) One could argue that this will leave us with a too large screen_pixmap in some cases, but rrCheckPixmapBounding only gets called for slave outputs, so xrandr clients already must manually shrink the screen_pixmap after disabling crtcs in normal setups. 2) An alternative approach would be to also call rrCheckPixmapBounding on RRSetCrtc on normal (non-slave) outputs, but that would result in 2 unnecessary resizes of the screen_pixmap in the above example, which seems undesirable. Cc: Nikhil Mahale Cc: Dave Airlie Signed-off-by: Hans de Goede Reviewed-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/rrcrtc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index 53508c96b3..54758bbdca 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -587,6 +587,12 @@ rrCheckPixmapBounding(ScreenPtr pScreen, new_width = newsize->x2; new_height = newsize->y2; + if (new_width < screen_pixmap->drawable.width) + new_width = screen_pixmap->drawable.width; + + if (new_height < screen_pixmap->drawable.height) + new_height = screen_pixmap->drawable.height; + if (new_width == screen_pixmap->drawable.width && new_height == screen_pixmap->drawable.height) { } else { From c2d9adf177f5bf9f19bfbbaa62332fdecd78e72c Mon Sep 17 00:00:00 2001 From: Michal Srb Date: Fri, 10 Mar 2017 14:16:26 +0100 Subject: [PATCH 14/33] xinerama: Swap the response in RRXineramaWriteMonitor Backported from X.org: commit c96c860b6420adf0d004707a323af30491a1d7d3 Author: Michal Srb Date: Mon Dec 12 17:45:22 2016 +0200 xinerama: Swap the response in RRXineramaWriteMonitor Reviewed-by: Adam Jackson Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/rrxinerama.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nx-X11/programs/Xserver/randr/rrxinerama.c b/nx-X11/programs/Xserver/randr/rrxinerama.c index d863897a78..b75b2ace91 100644 --- a/nx-X11/programs/Xserver/randr/rrxinerama.c +++ b/nx-X11/programs/Xserver/randr/rrxinerama.c @@ -303,6 +303,13 @@ RRXineramaWriteMonitor(ClientPtr client, RRMonitorPtr monitor) scratch.width = monitor->geometry.box.x2 - monitor->geometry.box.x1; scratch.height = monitor->geometry.box.y2 - monitor->geometry.box.y1; + if (client->swapped) { + swaps(&scratch.x_org); + swaps(&scratch.y_org); + swaps(&scratch.width); + swaps(&scratch.height); + } + WriteToClient(client, sz_XineramaScreenInfo, &scratch); } From 6f638c3fa3b7f0ab15fa1e912838364ea732f9b1 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Fri, 10 Mar 2017 14:20:43 +0100 Subject: [PATCH 15/33] randr: fix xserver crash when xrandr setprovideroutputsource Backported from X.org (and not-yet-enabled in NXAGENT_SERVER): commit 555e0a42d138ac8d83af62638752a1bebad602d6 Author: Qiang Yu Date: Tue Jan 10 18:51:55 2017 +0800 randr: fix xserver crash when xrandr setprovideroutputsource xrandr --setprovideroutputsource Xorg: ../../../xserver/dix/dispatch.c:4018: AttachOutputGPU: Assertion `new->isGPU' failed. GPUScreen is not allowed to be sink output. Signed-off-by: Qiang Yu Reviewed-by: Hans de Goede Signed-off-by: Peter Hutterer Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/rrprovider.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nx-X11/programs/Xserver/randr/rrprovider.c b/nx-X11/programs/Xserver/randr/rrprovider.c index e254111818..01900ae450 100644 --- a/nx-X11/programs/Xserver/randr/rrprovider.c +++ b/nx-X11/programs/Xserver/randr/rrprovider.c @@ -306,6 +306,11 @@ ProcRRSetProviderOutputSource(ClientPtr client) pScreen = provider->pScreen; pScrPriv = rrGetScrPriv(pScreen); +#ifndef NXAGENT_SERVER + if (!pScreen->isGPU) + return BadValue; +#endif + pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider); provider->changed = TRUE; From 52fdf573b7a51faaf5e5831aca0897e43cee8146 Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Wed, 22 Feb 2017 13:30:48 +0100 Subject: [PATCH 16/33] Add CreatePixmap allocation hints. Backported from X.org: commit f2e310132fbe1520c1b5f3da4faa2d2d47835e72 Author: Aaron Plattner Date: Wed Oct 31 14:15:35 2007 -0700 Add CreatePixmap allocation hints. These hints allow an acceleration architecture to optimize allocation of certain types of pixmaps, such as pixmaps that will serve as backing pixmaps for redirected windows. Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/Xext/shm.c | 5 +++-- nx-X11/programs/Xserver/composite/compalloc.c | 4 ++-- nx-X11/programs/Xserver/dbe/midbe.c | 8 ++++---- nx-X11/programs/Xserver/dix/dispatch.c | 2 +- nx-X11/programs/Xserver/dix/gc.c | 4 ++-- nx-X11/programs/Xserver/dix/glyphcurs.c | 3 ++- nx-X11/programs/Xserver/dix/pixmap.c | 2 +- nx-X11/programs/Xserver/dix/window.c | 2 +- nx-X11/programs/Xserver/fb/fb.h | 5 +++-- nx-X11/programs/Xserver/fb/fboverlay.c | 2 +- nx-X11/programs/Xserver/fb/fbpixmap.c | 3 ++- nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c | 3 ++- nx-X11/programs/Xserver/hw/nxagent/NXrender.c | 3 ++- nx-X11/programs/Xserver/hw/nxagent/NXshm.c | 7 ++++--- nx-X11/programs/Xserver/hw/nxagent/NXwindow.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Pixmap.c | 2 +- nx-X11/programs/Xserver/include/scrnintstr.h | 10 +++++++++- nx-X11/programs/Xserver/mi/miarc.c | 3 ++- nx-X11/programs/Xserver/mi/mibitblt.c | 6 ++++-- nx-X11/programs/Xserver/mi/mibstore.c | 7 ++++--- nx-X11/programs/Xserver/mi/midispcur.c | 11 ++++++----- nx-X11/programs/Xserver/mi/miglblt.c | 3 ++- nx-X11/programs/Xserver/mi/miscrinit.c | 2 +- nx-X11/programs/Xserver/render/mirect.c | 3 ++- nx-X11/programs/Xserver/render/mitrap.c | 2 +- nx-X11/programs/Xserver/render/render.c | 3 ++- 26 files changed, 65 insertions(+), 42 deletions(-) diff --git a/nx-X11/programs/Xserver/Xext/shm.c b/nx-X11/programs/Xserver/Xext/shm.c index 263adc3df8..ae0ef487e1 100644 --- a/nx-X11/programs/Xserver/Xext/shm.c +++ b/nx-X11/programs/Xserver/Xext/shm.c @@ -506,7 +506,8 @@ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data) putGC = GetScratchGC(depth, dst->pScreen); if (!putGC) return; - pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth); + pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pmap) { FreeScratchGC(putGC); @@ -1052,7 +1053,7 @@ fbShmCreatePixmap (pScreen, width, height, depth, addr) { register PixmapPtr pPixmap; - pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth); + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); if (!pPixmap) return NullPixmap; diff --git a/nx-X11/programs/Xserver/composite/compalloc.c b/nx-X11/programs/Xserver/composite/compalloc.c index e24c490d26..22b0362657 100644 --- a/nx-X11/programs/Xserver/composite/compalloc.c +++ b/nx-X11/programs/Xserver/composite/compalloc.c @@ -539,8 +539,8 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h) PixmapPtr pPixmap; /* usage_hint unsupported by our old server infrastructure. */ - pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth /*, - CREATE_PIXMAP_USAGE_BACKING_PIXMAP */); + pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth, + CREATE_PIXMAP_USAGE_BACKING_PIXMAP); if (!pPixmap) return 0; diff --git a/nx-X11/programs/Xserver/dbe/midbe.c b/nx-X11/programs/Xserver/dbe/midbe.c index bc8dd242e0..e241e5f281 100644 --- a/nx-X11/programs/Xserver/dbe/midbe.c +++ b/nx-X11/programs/Xserver/dbe/midbe.c @@ -188,7 +188,7 @@ miDbeAllocBackBufferName(pWin, bufId, swapAction) if (!(pDbeWindowPrivPriv->pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, pDbeWindowPriv->height, - pWin->drawable.depth))) + pWin->drawable.depth, 0))) { return(BadAlloc); } @@ -197,7 +197,7 @@ miDbeAllocBackBufferName(pWin, bufId, swapAction) if (!(pDbeWindowPrivPriv->pBackBuffer = (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, pDbeWindowPriv->height, - pWin->drawable.depth))) + pWin->drawable.depth, 0))) { (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); return(BadAlloc); @@ -668,10 +668,10 @@ miDbePositionWindow(pWin, x, y) /* Create DBE buffer pixmaps equal to size of resized window. */ pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, - pWin->drawable.depth); + pWin->drawable.depth, 0); pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, - pWin->drawable.depth); + pWin->drawable.depth, 0); if (!pFrontBuffer || !pBackBuffer) { diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 7b2aa7b3d3..a35f2f9988 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -1487,7 +1487,7 @@ ProcCreatePixmap(register ClientPtr client) CreatePmap: pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap) (pDraw->pScreen, stuff->width, - stuff->height, stuff->depth); + stuff->height, stuff->depth, 0); if (pMap) { pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; diff --git a/nx-X11/programs/Xserver/dix/gc.c b/nx-X11/programs/Xserver/dix/gc.c index b3a4edf4d1..d40334f5f5 100644 --- a/nx-X11/programs/Xserver/dix/gc.c +++ b/nx-X11/programs/Xserver/dix/gc.c @@ -694,7 +694,7 @@ CreateDefaultTile (GCPtr pGC) (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen); pTile = (PixmapPtr) (*pGC->pScreen->CreatePixmap)(pGC->pScreen, - w, h, pGC->depth); + w, h, pGC->depth, 0); pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen); if (!pTile || !pgcScratch) { @@ -1047,7 +1047,7 @@ CreateDefaultStipple(int screenNum) h = 16; (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen); if (!(pScreen->PixmapPerDepth[0] = - (*pScreen->CreatePixmap)(pScreen, w, h, 1))) + (*pScreen->CreatePixmap)(pScreen, w, h, 1, 0))) return FALSE; /* fill stipple with 1 */ tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid; diff --git a/nx-X11/programs/Xserver/dix/glyphcurs.c b/nx-X11/programs/Xserver/dix/glyphcurs.c index 08d67b922d..5e36f158c6 100644 --- a/nx-X11/programs/Xserver/dix/glyphcurs.c +++ b/nx-X11/programs/Xserver/dix/glyphcurs.c @@ -99,7 +99,8 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, uns bzero(pbits, nby); ppix = (PixmapPtr)(*pScreen->CreatePixmap)(pScreen, cm->width, - cm->height, 1); + cm->height, 1, + CREATE_PIXMAP_USAGE_SCRATCH); pGC = GetScratchGC(1, pScreen); if (!ppix || !pGC) { diff --git a/nx-X11/programs/Xserver/dix/pixmap.c b/nx-X11/programs/Xserver/dix/pixmap.c index 1f2239c121..747120b48e 100644 --- a/nx-X11/programs/Xserver/dix/pixmap.c +++ b/nx-X11/programs/Xserver/dix/pixmap.c @@ -59,7 +59,7 @@ GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth, pScreen->pScratchPixmap = NULL; else /* width and height of 0 means don't allocate any pixmap data */ - pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth); + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); if (pPixmap) { if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth, diff --git a/nx-X11/programs/Xserver/dix/window.c b/nx-X11/programs/Xserver/dix/window.c index a7346e778c..ba9cfc2d2b 100644 --- a/nx-X11/programs/Xserver/dix/window.c +++ b/nx-X11/programs/Xserver/dix/window.c @@ -295,7 +295,7 @@ MakeRootTile(WindowPtr pWin) register int i, j; pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4, - pScreen->rootDepth); + pScreen->rootDepth, 0); pWin->backgroundState = BackgroundPixmap; pGC = GetScratchGC(pScreen->rootDepth, pScreen); diff --git a/nx-X11/programs/Xserver/fb/fb.h b/nx-X11/programs/Xserver/fb/fb.h index 58aa8561ba..eb0cce33c5 100644 --- a/nx-X11/programs/Xserver/fb/fb.h +++ b/nx-X11/programs/Xserver/fb/fb.h @@ -1596,10 +1596,11 @@ fbPictureInit (ScreenPtr pScreen, */ PixmapPtr -fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp); +fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, + unsigned usage_hint); PixmapPtr -fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth); +fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint); Bool fbDestroyPixmap (PixmapPtr pPixmap); diff --git a/nx-X11/programs/Xserver/fb/fboverlay.c b/nx-X11/programs/Xserver/fb/fboverlay.c index e51f922f5a..8c723da4e2 100644 --- a/nx-X11/programs/Xserver/fb/fboverlay.c +++ b/nx-X11/programs/Xserver/fb/fboverlay.c @@ -140,7 +140,7 @@ fbOverlayCreateScreenResources(ScreenPtr pScreen) pbits = pScrPriv->layer[i].u.init.pbits; width = pScrPriv->layer[i].u.init.width; depth = pScrPriv->layer[i].u.init.depth; - pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth); + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); if (!pPixmap) return FALSE; if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width, diff --git a/nx-X11/programs/Xserver/fb/fbpixmap.c b/nx-X11/programs/Xserver/fb/fbpixmap.c index a2b98bc3cf..abdbc54a9f 100644 --- a/nx-X11/programs/Xserver/fb/fbpixmap.c +++ b/nx-X11/programs/Xserver/fb/fbpixmap.c @@ -86,7 +86,8 @@ fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp) } PixmapPtr -fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth) +fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, + unsigned usage_hint) { int bpp; bpp = BitsPerPixel (depth); diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c index 8b875555f0..549ab4333a 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c @@ -114,7 +114,8 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, uns /* zeroing the (pad) bits seems to help some ddx cursor handling */ bzero(pbits, nby); - ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1); + ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1, + CREATE_PIXMAP_USAGE_SCRATCH); pGC = GetScratchGC(1, pScreen); if (!ppix || !pGC) { diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c index ef288db0b1..c1a4577bde 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c @@ -1266,7 +1266,8 @@ ProcRenderCreateCursor (ClientPtr client) free (mskbits); return (BadImplementation); } - pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32); + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) { free (argbbits); diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c index f251f3b9f2..2ffca80663 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c @@ -173,7 +173,8 @@ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data) nxagentShmTrap = 1; return; } - pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth); + pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pmap) { nxagentShmTrap = 1; @@ -387,7 +388,7 @@ fbShmCreatePixmap (pScreen, width, height, depth, addr) nxagentShmPixmapTrap = 1; - pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth); + pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth, 0); if (!pPixmap) { @@ -397,7 +398,7 @@ fbShmCreatePixmap (pScreen, width, height, depth, addr) } #ifdef TEST - fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth); + fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d] Hint[%d]\n", width, height, depth, 0); #endif if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth, diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c index adff36569a..7de25ca281 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c @@ -162,7 +162,7 @@ MakeRootTile(WindowPtr pWin) register int i, j; pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4, - pScreen->rootDepth); + pScreen->rootDepth, 0); pWin->backgroundState = BackgroundPixmap; pGC = GetScratchGC(pScreen->rootDepth, pScreen); diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c index 05558e34f5..87cf136cc9 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c @@ -242,7 +242,7 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, * Create the pixmap in the virtual framebuffer. */ - pVirtual = fbCreatePixmap(pScreen, width, height, depth); + pVirtual = fbCreatePixmap(pScreen, width, height, depth, 0); if (pVirtual == NULL) { diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index b1b36c5d8d..80dcd33213 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -197,11 +197,19 @@ typedef void (* ClipNotifyProcPtr)( int /*dx*/, int /*dy*/); +/* pixmap will exist only for the duration of the current rendering operation */ +#define CREATE_PIXMAP_USAGE_SCRATCH 1 +/* pixmap will be the backing pixmap for a redirected window */ +#define CREATE_PIXMAP_USAGE_BACKING_PIXMAP 2 +/* pixmap will contain a glyph */ +#define CREATE_PIXMAP_USAGE_GLYPH_PICTURE 3 + typedef PixmapPtr (* CreatePixmapProcPtr)( ScreenPtr /*pScreen*/, int /*width*/, int /*height*/, - int /*depth*/); + int /*depth*/, + unsigned /*usage_hint*/); typedef Bool (* DestroyPixmapProcPtr)( PixmapPtr /*pPixmap*/); diff --git a/nx-X11/programs/Xserver/mi/miarc.c b/nx-X11/programs/Xserver/mi/miarc.c index bd46a243a2..5695e24af3 100644 --- a/nx-X11/programs/Xserver/mi/miarc.c +++ b/nx-X11/programs/Xserver/mi/miarc.c @@ -1184,7 +1184,8 @@ miPolyArc(pDraw, pGC, narcs, parcs) /* allocate a 1 bit deep pixmap of the appropriate size, and * validate it */ pDrawTo = (DrawablePtr)(*pDraw->pScreen->CreatePixmap) - (pDraw->pScreen, pixmapWidth, pixmapHeight, 1); + (pDraw->pScreen, pixmapWidth, pixmapHeight, 1, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pDrawTo) { FreeScratchGC(pGCTo); diff --git a/nx-X11/programs/Xserver/mi/mibitblt.c b/nx-X11/programs/Xserver/mi/mibitblt.c index 2fdc325006..67d36a7423 100644 --- a/nx-X11/programs/Xserver/mi/mibitblt.c +++ b/nx-X11/programs/Xserver/mi/mibitblt.c @@ -420,7 +420,8 @@ miOpqStipDrawable(pDraw, pGC, prgnSrc, pbits, srcx, w, h, dstx, dsty) RegionPtr prgnSrcClip; pPixmap = (*pDraw->pScreen->CreatePixmap) - (pDraw->pScreen, w + srcx, h, 1); + (pDraw->pScreen, w + srcx, h, 1, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) return; @@ -671,7 +672,8 @@ miGetImage(pDraw, sx, sy, w, h, format, planeMask, pDst) if (!pGC) return; pPixmap = (*pDraw->pScreen->CreatePixmap) - (pDraw->pScreen, w, 1, depth); + (pDraw->pScreen, w, 1, depth, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) { FreeScratchGC(pGC); diff --git a/nx-X11/programs/Xserver/mi/mibstore.c b/nx-X11/programs/Xserver/mi/mibstore.c index 5fddc85732..ec8a7aacbd 100644 --- a/nx-X11/programs/Xserver/mi/mibstore.c +++ b/nx-X11/programs/Xserver/mi/mibstore.c @@ -494,7 +494,8 @@ miBSGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine) XID subWindowMode = IncludeInferiors; int x, y; - pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, depth); + pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, depth, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) goto punt; pGC = GetScratchGC (depth, pScreen); @@ -2738,7 +2739,7 @@ miResizeBackingStore( pNewPixmap = (PixmapPtr)(*pScreen->CreatePixmap) (pScreen, nw, nh, - pWin->drawable.depth); + pWin->drawable.depth, 0); if (!pNewPixmap) { #ifdef BSEAGER @@ -3738,7 +3739,7 @@ miCreateBSPixmap (pWin, pExtents) (pScreen, extents->x2 - extents->x1, extents->y2 - extents->y1, - pWin->drawable.depth); + pWin->drawable.depth, 0); } if (!pBackingStore->pBackingPixmap) { diff --git a/nx-X11/programs/Xserver/mi/midispcur.c b/nx-X11/programs/Xserver/mi/midispcur.c index 2ed908de47..9eae75813c 100644 --- a/nx-X11/programs/Xserver/mi/midispcur.c +++ b/nx-X11/programs/Xserver/mi/midispcur.c @@ -267,7 +267,8 @@ miDCRealize ( pPriv->sourceBits = 0; pPriv->maskBits = 0; pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, - pCursor->bits->height, 32); + pCursor->bits->height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) { free ((void *) pPriv); @@ -299,13 +300,13 @@ miDCRealize ( } pPriv->pPicture = 0; #endif - pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1); + pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); if (!pPriv->sourceBits) { free ((void *) pPriv); return (miDCCursorPtr)NULL; } - pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1); + pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); if (!pPriv->maskBits) { (*pScreen->DestroyPixmap) (pPriv->sourceBits); @@ -526,7 +527,7 @@ miDCSaveUnderCursor (pScreen, x, y, w, h) if (pSave) (*pScreen->DestroyPixmap) (pSave); pScreenPriv->pSave = pSave = - (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth); + (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0); if (!pSave) return FALSE; } @@ -736,7 +737,7 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) } #endif pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap) - (pScreen, w, h, pScreenPriv->pSave->drawable.depth); + (pScreen, w, h, pScreenPriv->pSave->drawable.depth, 0); if (!pTemp) return FALSE; } diff --git a/nx-X11/programs/Xserver/mi/miglblt.c b/nx-X11/programs/Xserver/mi/miglblt.c index e317541a4f..5b72a92062 100644 --- a/nx-X11/programs/Xserver/mi/miglblt.c +++ b/nx-X11/programs/Xserver/mi/miglblt.c @@ -120,7 +120,8 @@ miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) FONTMAXBOUNDS(pfont,descent); pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen, - width, height, 1); + width, height, 1, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) return; diff --git a/nx-X11/programs/Xserver/mi/miscrinit.c b/nx-X11/programs/Xserver/mi/miscrinit.c index ac782cf7df..099ed6dcc1 100644 --- a/nx-X11/programs/Xserver/mi/miscrinit.c +++ b/nx-X11/programs/Xserver/mi/miscrinit.c @@ -161,7 +161,7 @@ miCreateScreenResources(pScreen) /* create a pixmap with no data, then redirect it to point to * the screen */ - pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth); + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); if (!pPixmap) return FALSE; diff --git a/nx-X11/programs/Xserver/render/mirect.c b/nx-X11/programs/Xserver/render/mirect.c index 3ce7a7f4c2..8884921407 100644 --- a/nx-X11/programs/Xserver/render/mirect.c +++ b/nx-X11/programs/Xserver/render/mirect.c @@ -137,7 +137,8 @@ miCompositeRects (CARD8 op, goto bail1; pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, - rgbaFormat->depth); + rgbaFormat->depth, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) goto bail2; diff --git a/nx-X11/programs/Xserver/render/mitrap.c b/nx-X11/programs/Xserver/render/mitrap.c index 96f1159a41..d3d052800f 100644 --- a/nx-X11/programs/Xserver/render/mitrap.c +++ b/nx-X11/programs/Xserver/render/mitrap.c @@ -62,7 +62,7 @@ miCreateAlphaPicture (ScreenPtr pScreen, } pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, - pPictFormat->depth); + pPictFormat->depth, 0); if (!pPixmap) return 0; pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); diff --git a/nx-X11/programs/Xserver/render/render.c b/nx-X11/programs/Xserver/render/render.c index 43cb430aa2..24a8675f6c 100644 --- a/nx-X11/programs/Xserver/render/render.c +++ b/nx-X11/programs/Xserver/render/render.c @@ -1570,7 +1570,8 @@ ProcRenderCreateCursor (ClientPtr client) free (mskbits); return (BadImplementation); } - pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32); + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) { free (argbbits); From edb2a9e599feeebb7b2e8b2afa05dd73f8a219f3 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Sat, 11 Mar 2017 01:13:58 +0100 Subject: [PATCH 17/33] Mesa.patches: Adapt Mesa to CreatePixmap allocation hint ABI bump. --- .../4001_CreatePixmap-AllocationHints.patch | 13 +++++++++++++ nx-X11/extras/Mesa.patches/series | 1 + 2 files changed, 14 insertions(+) create mode 100644 nx-X11/extras/Mesa.patches/4001_CreatePixmap-AllocationHints.patch create mode 100644 nx-X11/extras/Mesa.patches/series diff --git a/nx-X11/extras/Mesa.patches/4001_CreatePixmap-AllocationHints.patch b/nx-X11/extras/Mesa.patches/4001_CreatePixmap-AllocationHints.patch new file mode 100644 index 0000000000..f2caf28123 --- /dev/null +++ b/nx-X11/extras/Mesa.patches/4001_CreatePixmap-AllocationHints.patch @@ -0,0 +1,13 @@ +Index: Mesa/include/GL/xmesa_xf86.h +=================================================================== +--- Mesa.orig/include/GL/xmesa_xf86.h ++++ Mesa/include/GL/xmesa_xf86.h +@@ -130,7 +130,7 @@ do { \ + + /* CreatePixmap returns a PixmapPtr; so, it cannot be inside braces */ + #define XMesaCreatePixmap(__d,__b,__w,__h,__depth) \ +- (*__d->CreatePixmap)(__d, __w, __h, __depth) ++ (*__d->CreatePixmap)(__d, __w, __h, __depth, 0) + + #define XMesaFreePixmap(__d,__b) \ + (*__d->DestroyPixmap)(__b) diff --git a/nx-X11/extras/Mesa.patches/series b/nx-X11/extras/Mesa.patches/series new file mode 100644 index 0000000000..2ddad71d66 --- /dev/null +++ b/nx-X11/extras/Mesa.patches/series @@ -0,0 +1 @@ +4001_CreatePixmap-AllocationHints.patch From 3377b02deb7d641323b664c15743ee46c6524d13 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 22 Feb 2017 12:59:07 +0000 Subject: [PATCH 18/33] hw/nxagent/Pixmap.c et al.: Propagate usage_hint through nxagentCreatePixmap, as well. --- nx-X11/programs/Xserver/hw/nxagent/Drawable.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/NXglyph.c | 4 ++- nx-X11/programs/Xserver/hw/nxagent/Pixmap.c | 31 +++++++++++-------- nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h | 2 +- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 2 +- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c index 8d6f4139d4..5b8b291572 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c @@ -2702,7 +2702,7 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable) * would fail. */ - pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth); + pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth, CREATE_PIXMAP_USAGE_SCRATCH); if (pBitmap == NULL) { diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c index 7bf285d1f3..34195808d3 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c @@ -245,7 +245,9 @@ miGlyphs (CARD8 op, return; width = extents.x2 - extents.x1; height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth); + pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + maskFormat->depth, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pMaskPixmap) return; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c index 87cf136cc9..0942afafdf 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c @@ -96,8 +96,8 @@ struct nxagentPixmapPair PixmapPtr pMap; }; -PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, - int height, int depth) +PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, int height, + int depth, unsigned usage_hint) { nxagentPrivPixmapPtr pPixmapPriv, pVirtualPriv; @@ -106,7 +106,8 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, #ifdef DEBUG fprintf(stderr, "nxagentCreatePixmap: Creating pixmap with width [%d] " - "height [%d] depth [%d].\n", width, height, depth); + "height [%d] depth [%d] and allocation hint [%d].\n", + width, height, depth, usage_hint); #endif /* @@ -120,7 +121,8 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, { #ifdef WARNING fprintf(stderr, "nxagentCreatePixmap: WARNING! Failed to create pixmap with " - "width [%d] height [%d] depth [%d].\n", width, height, depth); + "width [%d] height [%d] depth [%d] and allocation hint [%d].\n", + width, height, depth, usage_hint); #endif return NullPixmap; @@ -242,13 +244,14 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, * Create the pixmap in the virtual framebuffer. */ - pVirtual = fbCreatePixmap(pScreen, width, height, depth, 0); + pVirtual = fbCreatePixmap(pScreen, width, height, depth, usage_hint); if (pVirtual == NULL) { #ifdef PANIC fprintf(stderr, "nxagentCreatePixmap: PANIC! Failed to create virtual pixmap with " - "width [%d] height [%d] depth [%d].\n", width, height, depth); + "width [%d] height [%d] depth [%d] and allocation hint [%d].\n", + width, height, depth, usage_hint); #endif nxagentDestroyPixmap(pPixmap); @@ -257,8 +260,9 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, } #ifdef TEST - fprintf(stderr,"nxagentCreatePixmap: Allocated memory for the Virtual %sPixmap %p of real Pixmap %p (%dx%d)\n", - nxagentShmPixmapTrap ? "Shm " : "", (void *) pVirtual, (void *) pPixmap, width, height); + fprintf(stderr,"nxagentCreatePixmap: Allocated memory for the Virtual %sPixmap %p of real Pixmap %p (%dx%d),", + "allocation hint [%d].\n", + nxagentShmPixmapTrap ? "Shm " : "", (void *) pVirtual, (void *) pPixmap, width, height, usage_hint); #endif pPixmapPriv -> pVirtualPixmap = pVirtual; @@ -330,10 +334,11 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, "bits per pixel.\n", (void *) pVirtual); fprintf(stderr, "nxagentCreatePixmap: WARNING! Real pixmap created with width [%d] " - "height [%d] depth [%d] bits per pixel [%d].\n", pPixmap -> drawable.width, + "height [%d] depth [%d] bits per pixel [%d] and allocation hint [%d].\n", + pPixmap -> drawable.width, pPixmap -> drawable.height = height, pPixmap -> drawable.depth, - pPixmap -> drawable.bitsPerPixel); - + pPixmap -> drawable.bitsPerPixel, + usage_hint); #endif if (!nxagentRenderTrap) @@ -352,8 +357,8 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, #ifdef TEST fprintf(stderr, "nxagentCreatePixmap: Created pixmap at [%p] virtual at [%p] with width [%d] " - "height [%d] depth [%d].\n", (void *) pPixmap, (void *) pVirtual, - width, height, depth); + "height [%d] depth [%d] and allocation hint [%d].\n", + (void *) pPixmap, (void *) pVirtual, width, height, depth, usage_hint); #endif return pPixmap; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h index d823cd77bc..00cc39c5f3 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h @@ -117,7 +117,7 @@ extern int nxagentPixmapPrivateIndex; PixmapPtr nxagentPixmapPtr(Pixmap pixmap); PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, - int height, int depth); + int height, int depth, unsigned usage_hint); Bool nxagentDestroyPixmap(PixmapPtr pPixmap); diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 01d8c1fc73..7f787c564e 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -2855,7 +2855,7 @@ int nxagentShadowCreateMainWindow(ScreenPtr pScreen, WindowPtr pWin, int width, DeleteWindow(nxagentShadowWindowPtr, accessWindowID); } - nxagentShadowPixmapPtr = nxagentCreatePixmap(pScreen, nxagentShadowWidth, nxagentShadowHeight, nxagentShadowDepth); + nxagentShadowPixmapPtr = nxagentCreatePixmap(pScreen, nxagentShadowWidth, nxagentShadowHeight, nxagentShadowDepth, 0); if (nxagentShadowPixmapPtr) { From 03850d692c177726dcbc279cd431e18f0df9cdf9 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 22 Feb 2017 14:14:41 +0100 Subject: [PATCH 19/33] Save pixmap allocation hints into the PixmapRec. Backported from X.org: commit f797c96845a3fab37cda6839ebecf9ac5401fd6e Author: Aaron Plattner Date: Thu Nov 15 12:12:02 2007 -0800 Save pixmap allocation hints into the PixmapRec. Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/fb/fb24_32.c | 2 +- nx-X11/programs/Xserver/fb/fbpixmap.c | 6 ++++-- nx-X11/programs/Xserver/hw/nxagent/Pixmap.c | 1 + nx-X11/programs/Xserver/include/pixmapstr.h | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/nx-X11/programs/Xserver/fb/fb24_32.c b/nx-X11/programs/Xserver/fb/fb24_32.c index 13af3acb23..f80874e2f9 100644 --- a/nx-X11/programs/Xserver/fb/fb24_32.c +++ b/nx-X11/programs/Xserver/fb/fb24_32.c @@ -537,7 +537,7 @@ fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel) pOldTile->drawable.width, pOldTile->drawable.height, pOldTile->drawable.depth, - bitsPerPixel); + bitsPerPixel, 0); if (!pNewTile) return 0; fbGetDrawable (&pOldTile->drawable, diff --git a/nx-X11/programs/Xserver/fb/fbpixmap.c b/nx-X11/programs/Xserver/fb/fbpixmap.c index abdbc54a9f..5f24433e3b 100644 --- a/nx-X11/programs/Xserver/fb/fbpixmap.c +++ b/nx-X11/programs/Xserver/fb/fbpixmap.c @@ -31,7 +31,8 @@ #include "fb.h" PixmapPtr -fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp) +fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, + unsigned usage_hint) { PixmapPtr pPixmap; size_t datasize; @@ -81,6 +82,7 @@ fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp) pPixmap->screen_x = 0; pPixmap->screen_y = 0; #endif + pPixmap->usage_hint = usage_hint; return pPixmap; } @@ -95,7 +97,7 @@ fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, if (bpp == 32 && depth <= 24) bpp = fbGetScreenPrivate(pScreen)->pix32bpp; #endif - return fbCreatePixmapBpp (pScreen, width, height, depth, bpp); + return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, usage_hint); } Bool diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c index 0942afafdf..be5408d13f 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c @@ -146,6 +146,7 @@ PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, int height, pPixmap -> devKind = 0; pPixmap -> refcnt = 1; pPixmap -> devPrivate.ptr = NULL; + pPixmap -> usage_hint = usage_hint; /* * Initialize the privates of the real picture. diff --git a/nx-X11/programs/Xserver/include/pixmapstr.h b/nx-X11/programs/Xserver/include/pixmapstr.h index 5189c3e09b..82b96d456f 100644 --- a/nx-X11/programs/Xserver/include/pixmapstr.h +++ b/nx-X11/programs/Xserver/include/pixmapstr.h @@ -82,6 +82,7 @@ typedef struct _Pixmap { short screen_x; short screen_y; #endif + unsigned usage_hint; /* see CREATE_PIXMAP_USAGE_* */ } PixmapRec; #endif /* PIXMAPSTRUCT_H */ From 953a7c7145d62e1dd8da7b40077e9c65cc64d5ef Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 10 Mar 2017 15:29:07 +0100 Subject: [PATCH 20/33] dix: pixmap sharing infrastructure (v3) Backport from X.org: commit fd6c1bf0a3efced3ad4623dbd4716230a5f2419e Author: Dave Airlie Date: Thu May 24 16:03:19 2012 +0100 dix: pixmap sharing infrastructure (v3) This is a hooks for pixmap sharing and tracking. The pixmap sharing ones get an integer handle for the pixmap and use a handle to be the backing for a pixmap. The tracker interface is to be used when a GPU needs to track pixmaps to be updated for another GPU. v2: pass slave to sharing so it can use it to work out driver. v3: use void * as per keithp's suggestion. Reviewed-by: Keith Packard Reviewed-by: Adam Jackson Signed-off-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/scrnintstr.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index 80dcd33213..8c807c42c1 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -203,6 +203,8 @@ typedef void (* ClipNotifyProcPtr)( #define CREATE_PIXMAP_USAGE_BACKING_PIXMAP 2 /* pixmap will contain a glyph */ #define CREATE_PIXMAP_USAGE_GLYPH_PICTURE 3 +/* pixmap will be shared */ +#define CREATE_PIXMAP_USAGE_SHARED 4 typedef PixmapPtr (* CreatePixmapProcPtr)( ScreenPtr /*pScreen*/, @@ -540,6 +542,15 @@ typedef Bool (*ReplaceScanoutPixmapProcPtr)( PixmapPtr, /*pPixmap*/ Bool /*enable*/); +typedef Bool (*SharePixmapBackingProcPtr)(PixmapPtr, ScreenPtr, void **); + +typedef Bool (*SetSharedPixmapBackingProcPtr)(PixmapPtr, void *); + +typedef Bool (*StartPixmapTrackingProcPtr)(PixmapPtr, PixmapPtr, + int x, int y); + +typedef Bool (*StopPixmapTrackingProcPtr)(PixmapPtr, PixmapPtr); + typedef struct _Screen { int myNum; /* index of this instance in Screens[] */ ATOM id; @@ -727,6 +738,12 @@ typedef struct _Screen { MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap; + + SharePixmapBackingProcPtr SharePixmapBacking; + SetSharedPixmapBackingProcPtr SetSharedPixmapBacking; + + StartPixmapTrackingProcPtr StartPixmapTracking; + StopPixmapTrackingProcPtr StopPixmapTracking; } ScreenRec; static inline RegionPtr BitmapToRegion(ScreenPtr _pScreen, PixmapPtr pPix) { From a96761f71abf97f23b28aa00dbabf6b3aadd6120 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 10 Mar 2017 16:29:24 +0100 Subject: [PATCH 21/33] dix: Move AddScreen() over into dispatch.c and introduce init_screen() Partially pruned out of X.org commits: commit 987579c930bda803427a28cb82773c389f5110d6 Author: Peter Hutterer Date: Wed Apr 22 13:26:40 2009 +1000 dix: remove all but main() from main.c All other functions are pushed into where they seemed to fit. main.c is now linked separately into libmain.a and linked in by the various DDXs. Signed-off-by: Peter Hutterer commit 3478af3374abffa0c226ee077fda1fcfc0751e74 Author: Dave Airlie Date: Tue Jun 5 17:01:21 2012 +0100 screen: split out screen init code. (v2) This is a precursor for reusing this code to init gpu screens. v2: fixup int check as per Keith's review. Reviewed-by: Keith Packard Signed-off-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/dispatch.c | 212 ++++++++++++++++++++++++ nx-X11/programs/Xserver/dix/main.c | 217 +------------------------ 2 files changed, 214 insertions(+), 215 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index a35f2f9988..e467126997 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -124,6 +124,8 @@ int ProcInitialConnection(); extern xConnSetupPrefix connSetupPrefix; extern char *ConnectionInfo; +extern int screenPrivateCount; + Selection *CurrentSelections; int NumCurrentSelections; CallbackListPtr SelectionCallback = NULL; @@ -3951,3 +3953,213 @@ MarkClientException(ClientPtr client) { client->noClientException = -1; } + +/* + * This array encodes the answer to the question "what is the log base 2 + * of the number of pixels that fit in a scanline pad unit?" + * Note that ~0 is an invalid entry (mostly for the benefit of the reader). + */ +static int answer[6][4] = { + /* pad pad pad pad*/ + /* 8 16 32 64 */ + + { 3, 4, 5 , 6 }, /* 1 bit per pixel */ + { 1, 2, 3 , 4 }, /* 4 bits per pixel */ + { 0, 1, 2 , 3 }, /* 8 bits per pixel */ + { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ + { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ + { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ +}; + +/* + * This array gives the bytesperPixel value for cases where the number + * of bits per pixel is a multiple of 8 but not a power of 2. + */ +static int answerBytesPerPixel[ 33 ] = { + ~0, 0, ~0, ~0, /* 1 bit per pixel */ + 0, ~0, ~0, ~0, /* 4 bits per pixel */ + 0, ~0, ~0, ~0, /* 8 bits per pixel */ + ~0,~0, ~0, ~0, + 0, ~0, ~0, ~0, /* 16 bits per pixel */ + ~0,~0, ~0, ~0, + 3, ~0, ~0, ~0, /* 24 bits per pixel */ + ~0,~0, ~0, ~0, + 0 /* 32 bits per pixel */ +}; + +/* + * This array gives the answer to the question "what is the first index for + * the answer array above given the number of bits per pixel?" + * Note that ~0 is an invalid entry (mostly for the benefit of the reader). + */ +static int indexForBitsPerPixel[ 33 ] = { + ~0, 0, ~0, ~0, /* 1 bit per pixel */ + 1, ~0, ~0, ~0, /* 4 bits per pixel */ + 2, ~0, ~0, ~0, /* 8 bits per pixel */ + ~0,~0, ~0, ~0, + 3, ~0, ~0, ~0, /* 16 bits per pixel */ + ~0,~0, ~0, ~0, + 4, ~0, ~0, ~0, /* 24 bits per pixel */ + ~0,~0, ~0, ~0, + 5 /* 32 bits per pixel */ +}; + +/* + * This array gives the answer to the question "what is the second index for + * the answer array above given the number of bits per scanline pad unit?" + * Note that ~0 is an invalid entry (mostly for the benefit of the reader). + */ +static int indexForScanlinePad[ 65 ] = { + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ + ~0, ~0, ~0, ~0, + 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + ~0, ~0, ~0, ~0, + 3 /* 64 bits per scanline pad unit */ +}; + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +static int init_screen(ScreenPtr pScreen, int i) +{ + int scanlinepad, format, depth, bitsPerPixel, j, k; +#ifdef DEBUG + void (**jNI) (); +#endif /* DEBUG */ + + pScreen->myNum = i; + pScreen->WindowPrivateLen = 0; + pScreen->WindowPrivateSizes = (unsigned *)NULL; + pScreen->totalWindowSize = + ((sizeof(WindowRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long); + pScreen->GCPrivateLen = 0; + pScreen->GCPrivateSizes = (unsigned *)NULL; + pScreen->totalGCSize = + ((sizeof(GC) + sizeof(long) - 1) / sizeof(long)) * sizeof(long); +#ifdef PIXPRIV + pScreen->PixmapPrivateLen = 0; + pScreen->PixmapPrivateSizes = (unsigned *)NULL; + pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8); +#endif + pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ + pScreen->CreateScreenResources = 0; + +#ifdef DEBUG + for (jNI = &pScreen->QueryBestSize; + jNI < (void (**) ()) &pScreen->SendGraphicsExpose; + jNI++) + *jNI = NotImplemented; +#endif /* DEBUG */ + + /* + * This loop gets run once for every Screen that gets added, + * but thats ok. If the ddx layer initializes the formats + * one at a time calling AddScreen() after each, then each + * iteration will make it a little more accurate. Worst case + * we do this loop N * numPixmapFormats where N is # of screens. + * Anyway, this must be called after InitOutput and before the + * screen init routine is called. + */ + for (format=0; formatdevPrivates = (DevUnion *)calloc(sizeof(DevUnion), + screenPrivateCount); + if (!pScreen->devPrivates && screenPrivateCount) + return -1; + + ret = init_screen(pScreen, i); + if (ret != 0) { + free(pScreen); + return ret; + } + /* This is where screen specific stuff gets initialized. Load the + screen structure, call the hardware, whatever. + This is also where the default colormap should be allocated and + also pixel values for blackPixel, whitePixel, and the cursor + Note that InitScreen is NOT allowed to modify argc, argv, or + any of the strings pointed to by argv. They may be passed to + multiple screens. + */ + pScreen->rgf = ~0L; /* there are no scratch GCs yet*/ + screenInfo.screens[i] = pScreen; + screenInfo.numScreens++; + if (!(*pfnInit)(pScreen, argc, argv)) + { + FreeScreen(pScreen); + screenInfo.numScreens--; + return -1; + } + return i; +} + +void +FreeScreen(ScreenPtr pScreen) +{ + pScreen->root = NullWindow; + free(pScreen->WindowPrivateSizes); + free(pScreen->GCPrivateSizes); +#ifdef PIXPRIV + free(pScreen->PixmapPrivateSizes); +#endif + free(pScreen->devPrivates); + free(pScreen); +} diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 7bd41d865f..d01fe6c308 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -120,18 +120,17 @@ extern void Dispatch(void); xConnSetupPrefix connSetupPrefix; extern FontPtr defaultFont; -extern int screenPrivateCount; extern void InitProcVectors(void); extern Bool CreateGCperDepthArray(void); +extern void FreeScreen(ScreenPtr pScreen); + #ifndef PANORAMIX static #endif Bool CreateConnectionBlock(void); -static void FreeScreen(ScreenPtr); - PaddingInfo PixmapWidthPaddingInfo[33]; int connBlockScreenStart; @@ -158,85 +157,6 @@ ReplyNotSwappd( FatalError("Not implemented"); } -/* - * This array encodes the answer to the question "what is the log base 2 - * of the number of pixels that fit in a scanline pad unit?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int answer[6][4] = { - /* pad pad pad pad*/ - /* 8 16 32 64 */ - - { 3, 4, 5 , 6 }, /* 1 bit per pixel */ - { 1, 2, 3 , 4 }, /* 4 bits per pixel */ - { 0, 1, 2 , 3 }, /* 8 bits per pixel */ - { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ - { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ - { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ -}; - -/* - * This array gives the answer to the question "what is the first index for - * the answer array above given the number of bits per pixel?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int indexForBitsPerPixel[ 33 ] = { - ~0, 0, ~0, ~0, /* 1 bit per pixel */ - 1, ~0, ~0, ~0, /* 4 bits per pixel */ - 2, ~0, ~0, ~0, /* 8 bits per pixel */ - ~0,~0, ~0, ~0, - 3, ~0, ~0, ~0, /* 16 bits per pixel */ - ~0,~0, ~0, ~0, - 4, ~0, ~0, ~0, /* 24 bits per pixel */ - ~0,~0, ~0, ~0, - 5 /* 32 bits per pixel */ -}; - -/* - * This array gives the bytesperPixel value for cases where the number - * of bits per pixel is a multiple of 8 but not a power of 2. - */ -static int answerBytesPerPixel[ 33 ] = { - ~0, 0, ~0, ~0, /* 1 bit per pixel */ - 0, ~0, ~0, ~0, /* 4 bits per pixel */ - 0, ~0, ~0, ~0, /* 8 bits per pixel */ - ~0,~0, ~0, ~0, - 0, ~0, ~0, ~0, /* 16 bits per pixel */ - ~0,~0, ~0, ~0, - 3, ~0, ~0, ~0, /* 24 bits per pixel */ - ~0,~0, ~0, ~0, - 0 /* 32 bits per pixel */ -}; - -/* - * This array gives the answer to the question "what is the second index for - * the answer array above given the number of bits per scanline pad unit?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int indexForScanlinePad[ 65 ] = { - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 3 /* 64 bits per scanline pad unit */ -}; - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - int main(int argc, char *argv[], char *envp[]) { @@ -653,136 +573,3 @@ CreateConnectionBlock() connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; return TRUE; } - -/* - grow the array of screenRecs if necessary. - call the device-supplied initialization procedure -with its screen number, a pointer to its ScreenRec, argc, and argv. - return the number of successfully installed screens. - -*/ - -int -AddScreen( - Bool (* pfnInit)( - int /*index*/, - ScreenPtr /*pScreen*/, - int /*argc*/, - char ** /*argv*/ - ), - int argc, - char **argv) -{ - - int i; - int scanlinepad, format, depth, bitsPerPixel, j, k; - ScreenPtr pScreen; -#ifdef DEBUG - void (**jNI) (); -#endif /* DEBUG */ - - i = screenInfo.numScreens; - if (i == MAXSCREENS) - return -1; - - pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); - if (!pScreen) - return -1; - - pScreen->devPrivates = (DevUnion *)calloc(sizeof(DevUnion), - screenPrivateCount); - if (!pScreen->devPrivates && screenPrivateCount) - { - free(pScreen); - return -1; - } - pScreen->myNum = i; - pScreen->WindowPrivateLen = 0; - pScreen->WindowPrivateSizes = (unsigned *)NULL; - pScreen->totalWindowSize = - ((sizeof(WindowRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long); - pScreen->GCPrivateLen = 0; - pScreen->GCPrivateSizes = (unsigned *)NULL; - pScreen->totalGCSize = - ((sizeof(GC) + sizeof(long) - 1) / sizeof(long)) * sizeof(long); -#ifdef PIXPRIV - pScreen->PixmapPrivateLen = 0; - pScreen->PixmapPrivateSizes = (unsigned *)NULL; - pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8); -#endif - pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ - pScreen->CreateScreenResources = 0; - -#ifdef DEBUG - for (jNI = &pScreen->QueryBestSize; - jNI < (void (**) ()) &pScreen->SendGraphicsExpose; - jNI++) - *jNI = NotImplemented; -#endif /* DEBUG */ - - /* - * This loop gets run once for every Screen that gets added, - * but thats ok. If the ddx layer initializes the formats - * one at a time calling AddScreen() after each, then each - * iteration will make it a little more accurate. Worst case - * we do this loop N * numPixmapFormats where N is # of screens. - * Anyway, this must be called after InitOutput and before the - * screen init routine is called. - */ - for (format=0; formatrgf = ~0L; /* there are no scratch GCs yet*/ - screenInfo.screens[i] = pScreen; - screenInfo.numScreens++; - if (!(*pfnInit)(i, pScreen, argc, argv)) - { - FreeScreen(pScreen); - screenInfo.numScreens--; - return -1; - } - return i; -} - -static void -FreeScreen(ScreenPtr pScreen) -{ - pScreen->root = NullWindow; - free(pScreen->WindowPrivateSizes); - free(pScreen->GCPrivateSizes); -#ifdef PIXPRIV - free(pScreen->PixmapPrivateSizes); -#endif - free(pScreen->devPrivates); - free(pScreen); -} From 3924a102a71b8f2cdb9ca59c21e7fb21050ad938 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 10 Mar 2017 16:48:54 +0100 Subject: [PATCH 22/33] Move AddScreen() comment where it actually belongs. Should be done in X.org, too. --- nx-X11/programs/Xserver/dix/dispatch.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index e467126997..78e14949ff 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -4102,6 +4102,13 @@ static int init_screen(ScreenPtr pScreen, int i) void FreeScreen(ScreenPtr); +/* + grow the array of screenRecs if necessary. + call the device-supplied initialization procedure + with its screen number, a pointer to its ScreenRec, argc, and argv. + return the number of successfully installed screens. +*/ + int AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , int /*argc */ , From 84329a12308e600c263a755bc148c08520447cd2 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Feb 2017 12:54:14 +0100 Subject: [PATCH 23/33] Mesa subtree: Add quilt based patch system for bundled Mesa. --- Makefile | 3 +++ mesa-quilt | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100755 mesa-quilt diff --git a/Makefile b/Makefile index 4784f6d658..eb53f1ed25 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,8 @@ SHELL:=/bin/bash # clean auto-generated nxversion.def file \ if [ "x$@" == "xclean" ] || [ "x$@" = "xdistclean" ]; then \ + ./mesa-quilt pop -a; \ + rm -Rf nx-X11/extras/Mesa/.pc/; \ rm -f nx-X11/config/cf/nxversion.def; \ rm -f bin/nxagent; \ rm -f bin/nxproxy; \ @@ -72,6 +74,7 @@ build-full: cd nxcompshad && autoconf && (${CONFIGURE}) && ${MAKE} + ./mesa-quilt push -a cd nx-X11 && ${MAKE} World USRLIBDIR=$(USRLIBDIR) SHLIBDIR=$(SHLIBDIR) cd nxproxy && autoconf && (${CONFIGURE}) && ${MAKE} diff --git a/mesa-quilt b/mesa-quilt new file mode 100755 index 0000000000..a284bbaf01 --- /dev/null +++ b/mesa-quilt @@ -0,0 +1,34 @@ +#!/bin/bash + +# Copyright (C) 2017 by Mike Gabriel +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +d=. ; while [ ! -d $d/nx-X11/extras -a `readlink -e $d` != / ]; do d=$d/..; done +if [ -d $d/nx-X11/extras ] && [ -z $QUILT_PATCHES ]; then + # if in Debian packaging tree with unset $QUILT_PATCHES + export QUILT_PATCHES="../Mesa.patches" + export QUILT_PATCH_OPTS="--reject-format=unified" + export QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto" + export QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index" + export QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33" + if ! [ -d $d/nx-X11/extras/Mesa.patches ]; then mkdir $d/nx-X11/extras/Mesa.patches; fi + cd $d/nx-X11/extras/Mesa/ +fi + +quilt $@ + +cd - 1> /dev/null From b65272d58262ac7ae1657c9bee02c5c55a4987c0 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Sat, 11 Mar 2017 00:48:03 +0100 Subject: [PATCH 24/33] dix: Remove insane BC hacks commit 6b5206e7cb8e5279816b48f014d47d3f03f16972 Author: Daniel Stone Date: Fri Jul 18 15:38:10 2008 +0300 dix: Remove insane BC hacks If your DDX needs a 1bpp mode and doesn't set it up, your DDX is incompetent. Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/main.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index d01fe6c308..467dfc0f9e 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -160,7 +160,7 @@ ReplyNotSwappd( int main(int argc, char *argv[], char *envp[]) { - int i, j, k, error; + int i, error; char *xauthfile; HWEventQueueType alwaysCheckForInput[2]; @@ -249,17 +249,6 @@ main(int argc, char *argv[], char *envp[]) screenInfo.numScreens = 0; screenInfo.numVideoScreens = -1; - /* - * Just in case the ddx doesnt supply a format for depth 1 (like qvss). - */ - j = indexForBitsPerPixel[ 1 ]; - k = indexForScanlinePad[ BITMAP_SCANLINE_PAD ]; - PixmapWidthPaddingInfo[1].padRoundUp = BITMAP_SCANLINE_PAD-1; - PixmapWidthPaddingInfo[1].padPixelsLog2 = answer[j][k]; - j = indexForBitsPerPixel[8]; /* bits per byte */ - PixmapWidthPaddingInfo[1].padBytesLog2 = answer[j][k]; - PixmapWidthPaddingInfo[1].bitsPerPixel = 1; - InitAtoms(); InitEvents(); InitGlyphCaching(); From b5da76963725ff07524528e09df68aebed2fed08 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 11 Mar 2017 00:53:01 +0100 Subject: [PATCH 25/33] xserver: remove index from CloseScreen (API/ABI breakage) Extracted from X.org bulk commit: commit 1f0e8bd5eb1a5539689cfc4f5a6b86b530907ec5 Author: Dave Airlie Date: Tue Jun 5 13:22:18 2012 +0100 api: rework the X server driver API to avoid global arrays. This is a squash merge containing all the API changes, as well as the video ABI bump. Its been squashed to make bisection easier. Full patch log below: [...] commit 06729dbbc804a20242e6499f446acb5d94023c3c Author: Dave Airlie Date: Tue Apr 10 14:04:59 2012 +0100 xserver: remove index from CloseScreen (API/ABI breakage) This drops the index from the CloseScreen callback, its always been useless really, since the pScreen contains it. Reviewed-by: Alan Coopersmith Acked-by: Aaron Plattner Reviewed-by: Adam Jackson Signed-off-by: Dave Airlie --- nx-X11/programs/Xserver/Xext/panoramiX.c | 4 ++-- nx-X11/programs/Xserver/Xext/xvdix.h | 2 +- nx-X11/programs/Xserver/Xext/xvmain.c | 7 +++---- nx-X11/programs/Xserver/Xext/xvmc.c | 4 ++-- nx-X11/programs/Xserver/composite/compinit.c | 4 ++-- nx-X11/programs/Xserver/dix/main.c | 2 +- nx-X11/programs/Xserver/fb/fb.h | 2 +- nx-X11/programs/Xserver/fb/fboverlay.c | 2 +- nx-X11/programs/Xserver/fb/fboverlay.h | 2 +- nx-X11/programs/Xserver/fb/fbscreen.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 8 ++++---- nx-X11/programs/Xserver/hw/nxagent/Screen.h | 4 ++-- nx-X11/programs/Xserver/include/screenint.h | 1 - nx-X11/programs/Xserver/include/scrnintstr.h | 1 - nx-X11/programs/Xserver/mi/mi.h | 1 - nx-X11/programs/Xserver/mi/mibstore.c | 7 +++---- nx-X11/programs/Xserver/mi/midispcur.c | 7 +++---- nx-X11/programs/Xserver/mi/mioverlay.c | 6 +++--- nx-X11/programs/Xserver/mi/mipointer.c | 7 +++---- nx-X11/programs/Xserver/mi/miscrinit.c | 3 +-- nx-X11/programs/Xserver/mi/misprite.c | 7 +++---- nx-X11/programs/Xserver/miext/cw/cw.c | 6 +++--- nx-X11/programs/Xserver/miext/damage/damage.c | 4 ++-- nx-X11/programs/Xserver/randr/randr.c | 5 +---- nx-X11/programs/Xserver/render/animcur.c | 8 ++++---- nx-X11/programs/Xserver/render/picture.c | 4 ++-- nx-X11/programs/Xserver/render/picturestr.h | 2 +- nx-X11/programs/Xserver/xfixes/cursor.c | 8 ++++---- 28 files changed, 54 insertions(+), 66 deletions(-) diff --git a/nx-X11/programs/Xserver/Xext/panoramiX.c b/nx-X11/programs/Xserver/Xext/panoramiX.c index 3809890bc1..e720965d46 100644 --- a/nx-X11/programs/Xserver/Xext/panoramiX.c +++ b/nx-X11/programs/Xserver/Xext/panoramiX.c @@ -149,7 +149,7 @@ GCFuncs XineramaGCFuncs = { static Bool -XineramaCloseScreen (int i, ScreenPtr pScreen) +XineramaCloseScreen (ScreenPtr pScreen) { PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr) pScreen->devPrivates[PanoramiXScreenIndex].ptr; @@ -163,7 +163,7 @@ XineramaCloseScreen (int i, ScreenPtr pScreen) free ((void *) pScreenPriv); - return (*pScreen->CloseScreen) (i, pScreen); + return (*pScreen->CloseScreen) (pScreen); } Bool diff --git a/nx-X11/programs/Xserver/Xext/xvdix.h b/nx-X11/programs/Xserver/Xext/xvdix.h index 4e8fbb507c..973c39b761 100644 --- a/nx-X11/programs/Xserver/Xext/xvdix.h +++ b/nx-X11/programs/Xserver/Xext/xvdix.h @@ -219,7 +219,7 @@ typedef struct { DestroyWindowProcPtr DestroyWindow; DestroyPixmapProcPtr DestroyPixmap; CloseScreenProcPtr CloseScreen; - Bool (* ddCloseScreen)(int, ScreenPtr); + Bool (* ddCloseScreen)(ScreenPtr); int (* ddQueryAdaptors)(ScreenPtr, XvAdaptorPtr*, int*); DevUnion devPriv; } XvScreenRec, *XvScreenPtr; diff --git a/nx-X11/programs/Xserver/Xext/xvmain.c b/nx-X11/programs/Xserver/Xext/xvmain.c index 3eea84c76b..397f8dc816 100644 --- a/nx-X11/programs/Xserver/Xext/xvmain.c +++ b/nx-X11/programs/Xserver/Xext/xvmain.c @@ -131,7 +131,7 @@ static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); static Bool CreateResourceTypes(void); -static Bool XvCloseScreen(int, ScreenPtr); +static Bool XvCloseScreen(ScreenPtr); static Bool XvDestroyPixmap(PixmapPtr); static Bool XvDestroyWindow(WindowPtr); static void XvResetProc(ExtensionEntry*); @@ -307,7 +307,6 @@ XvScreenInit(ScreenPtr pScreen) static Bool XvCloseScreen( - int ii, ScreenPtr pScreen ){ @@ -319,13 +318,13 @@ XvCloseScreen( pScreen->DestroyWindow = pxvs->DestroyWindow; pScreen->CloseScreen = pxvs->CloseScreen; - (* pxvs->ddCloseScreen)(ii, pScreen); + (* pxvs->ddCloseScreen)(pScreen); free(pxvs); pScreen->devPrivates[XvScreenIndex].ptr = (void *)NULL; - return (*pScreen->CloseScreen)(ii, pScreen); + return (*pScreen->CloseScreen)(pScreen); } diff --git a/nx-X11/programs/Xserver/Xext/xvmc.c b/nx-X11/programs/Xserver/Xext/xvmc.c index 0a43baa22c..fcd170efd5 100644 --- a/nx-X11/programs/Xserver/Xext/xvmc.c +++ b/nx-X11/programs/Xserver/Xext/xvmc.c @@ -696,7 +696,7 @@ XvMCExtensionInit() } static Bool -XvMCCloseScreen (int i, ScreenPtr pScreen) +XvMCCloseScreen (ScreenPtr pScreen) { XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); @@ -704,7 +704,7 @@ XvMCCloseScreen (int i, ScreenPtr pScreen) free(pScreenPriv); - return (*pScreen->CloseScreen)(i, pScreen); + return (*pScreen->CloseScreen)(pScreen); } diff --git a/nx-X11/programs/Xserver/composite/compinit.c b/nx-X11/programs/Xserver/composite/compinit.c index c4d069dae2..ff21378873 100644 --- a/nx-X11/programs/Xserver/composite/compinit.c +++ b/nx-X11/programs/Xserver/composite/compinit.c @@ -40,7 +40,7 @@ int CompSubwindowsPrivIndex = -1; #endif static Bool -compCloseScreen (int index, ScreenPtr pScreen) +compCloseScreen (ScreenPtr pScreen) { CompScreenPtr cs = GetCompScreen (pScreen); Bool ret; @@ -78,7 +78,7 @@ compCloseScreen (int index, ScreenPtr pScreen) free (cs); FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, NULL); - ret = (*pScreen->CloseScreen) (index, pScreen); + ret = (*pScreen->CloseScreen) (pScreen); return ret; } diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 467dfc0f9e..82eab4b615 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -368,7 +368,7 @@ main(int argc, char *argv[], char *envp[]) FreeScratchPixmapsForScreen(i); FreeGCperDepth(i); FreeDefaultStipple(i); - (* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]); + (* screenInfo.screens[i]->CloseScreen)(screenInfo.screens[i]); FreeScreen(screenInfo.screens[i]); screenInfo.numScreens = i; } diff --git a/nx-X11/programs/Xserver/fb/fb.h b/nx-X11/programs/Xserver/fb/fb.h index eb0cce33c5..14738df2eb 100644 --- a/nx-X11/programs/Xserver/fb/fb.h +++ b/nx-X11/programs/Xserver/fb/fb.h @@ -1704,7 +1704,7 @@ fbPushPixels (GCPtr pGC, */ Bool -fbCloseScreen (int indx, ScreenPtr pScreen); +fbCloseScreen (ScreenPtr pScreen); Bool fbRealizeFont(ScreenPtr pScreen, FontPtr pFont); diff --git a/nx-X11/programs/Xserver/fb/fboverlay.c b/nx-X11/programs/Xserver/fb/fboverlay.c index 8c723da4e2..392ffc70b3 100644 --- a/nx-X11/programs/Xserver/fb/fboverlay.c +++ b/nx-X11/programs/Xserver/fb/fboverlay.c @@ -88,7 +88,7 @@ fbOverlayCreateWindow(WindowPtr pWin) } Bool -fbOverlayCloseScreen (int iScreen, ScreenPtr pScreen) +fbOverlayCloseScreen (ScreenPtr pScreen) { FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); int i; diff --git a/nx-X11/programs/Xserver/fb/fboverlay.h b/nx-X11/programs/Xserver/fb/fboverlay.h index d1469f22a5..478ecb565e 100644 --- a/nx-X11/programs/Xserver/fb/fboverlay.h +++ b/nx-X11/programs/Xserver/fb/fboverlay.h @@ -65,7 +65,7 @@ Bool fbOverlayCreateWindow(WindowPtr pWin); Bool -fbOverlayCloseScreen (int iScreen, ScreenPtr pScreen); +fbOverlayCloseScreen (ScreenPtr pScreen); int fbOverlayWindowLayer(WindowPtr pWin); diff --git a/nx-X11/programs/Xserver/fb/fbscreen.c b/nx-X11/programs/Xserver/fb/fbscreen.c index 4346e5f7b5..b0e6d9a6b3 100644 --- a/nx-X11/programs/Xserver/fb/fbscreen.c +++ b/nx-X11/programs/Xserver/fb/fbscreen.c @@ -29,7 +29,7 @@ #include "fb.h" Bool -fbCloseScreen (int index, ScreenPtr pScreen) +fbCloseScreen (ScreenPtr pScreen) { int d; DepthPtr depths = pScreen->allowedDepths; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 7f787c564e..1c3e765809 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -820,7 +820,7 @@ static int nxagentColorOffset(unsigned long mask) return count; } -Bool nxagentOpenScreen(int index, ScreenPtr pScreen, +Bool nxagentOpenScreen(ScreenPtr pScreen, int argc, char *argv[]) { VisualPtr visuals; @@ -846,7 +846,7 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen, #ifdef TEST fprintf(stderr, "nxagentOpenScreen: Called for screen index [%d].\n", - index); + pScreen->myNum); #endif if (nxagentRenderEnable && nxagentReconnectTrap == False) @@ -2075,7 +2075,7 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio return True; } -Bool nxagentCloseScreen(int index, ScreenPtr pScreen) +Bool nxagentCloseScreen(ScreenPtr pScreen) { int i; @@ -3552,7 +3552,7 @@ Bool nxagentReconnectScreen(void *p0) fprintf(stderr, "nxagentReconnectScreen\n"); #endif - if (!nxagentOpenScreen(0, nxagentDefaultScreen, nxagentArgc, nxagentArgv)) + if (!nxagentOpenScreen(nxagentDefaultScreen, nxagentArgc, nxagentArgv)) { return False; } diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h index caefbb0278..3df586fa8a 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h @@ -88,10 +88,10 @@ void nxagentInitViewportFrame(ScreenPtr pScreen, WindowPtr pRootWin); #endif /* #ifdef VIEWPORT_FRAME */ -Bool nxagentOpenScreen(int index, ScreenPtr pScreen, +Bool nxagentOpenScreen(ScreenPtr pScreen, int argc, char *argv[]); -Bool nxagentCloseScreen(int index, ScreenPtr pScreen); +Bool nxagentCloseScreen(ScreenPtr pScreen); #define nxagentScreen(window) nxagentDefaultScreen diff --git a/nx-X11/programs/Xserver/include/screenint.h b/nx-X11/programs/Xserver/include/screenint.h index e60c2480c7..abaa6f85b1 100644 --- a/nx-X11/programs/Xserver/include/screenint.h +++ b/nx-X11/programs/Xserver/include/screenint.h @@ -79,7 +79,6 @@ extern Bool AllocateGCPrivate( extern int AddScreen( Bool (* /*pfnInit*/)( - int /*index*/, ScreenPtr /*pScreen*/, int /*argc*/, char ** /*argv*/), diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index 8c807c42c1..99a2818765 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -89,7 +89,6 @@ typedef struct _Depth { */ typedef Bool (* CloseScreenProcPtr)( - int /*index*/, ScreenPtr /*pScreen*/); typedef void (* QueryBestSizeProcPtr)( diff --git a/nx-X11/programs/Xserver/mi/mi.h b/nx-X11/programs/Xserver/mi/mi.h index 0cd4b8bac7..409e21e343 100644 --- a/nx-X11/programs/Xserver/mi/mi.h +++ b/nx-X11/programs/Xserver/mi/mi.h @@ -437,7 +437,6 @@ extern Bool miModifyPixmapHeader( ); extern Bool miCloseScreen( - int /*index*/, ScreenPtr /*pScreen*/ ); diff --git a/nx-X11/programs/Xserver/mi/mibstore.c b/nx-X11/programs/Xserver/mi/mibstore.c index ec8a7aacbd..3eafac2353 100644 --- a/nx-X11/programs/Xserver/mi/mibstore.c +++ b/nx-X11/programs/Xserver/mi/mibstore.c @@ -183,7 +183,7 @@ else \ static int miBSScreenIndex; static unsigned long miBSGeneration = 0; -static Bool miBSCloseScreen(int i, ScreenPtr pScreen); +static Bool miBSCloseScreen(ScreenPtr pScreen); static void miBSGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, unsigned int format, unsigned long planemask, char *pdstLine); @@ -416,8 +416,7 @@ miInitializeBackingStore (pScreen) */ static Bool -miBSCloseScreen (i, pScreen) - int i; +miBSCloseScreen (pScreen) ScreenPtr pScreen; { miBSScreenPtr pScreenPriv; @@ -432,7 +431,7 @@ miBSCloseScreen (i, pScreen) free ((void *) pScreenPriv); - return (*pScreen->CloseScreen) (i, pScreen); + return (*pScreen->CloseScreen) (pScreen); } static void miBSFillVirtualBits(DrawablePtr pDrawable, GCPtr pGC, diff --git a/nx-X11/programs/Xserver/mi/midispcur.c b/nx-X11/programs/Xserver/mi/midispcur.c index 9eae75813c..92d0fb15c5 100644 --- a/nx-X11/programs/Xserver/mi/midispcur.c +++ b/nx-X11/programs/Xserver/mi/midispcur.c @@ -56,7 +56,7 @@ in this Software without prior written authorization from The Open Group. static int miDCScreenIndex; static unsigned long miDCGeneration = 0; -static Bool miDCCloseScreen(int index, ScreenPtr pScreen); +static Bool miDCCloseScreen(ScreenPtr pScreen); typedef struct { GCPtr pSourceGC, pMaskGC; @@ -163,8 +163,7 @@ miDCInitialize (pScreen, screenFuncs) #define tossPict(pict) (pict ? FreePicture (pict, 0) : 0) static Bool -miDCCloseScreen (index, pScreen) - int index; +miDCCloseScreen (pScreen) ScreenPtr pScreen; { miDCScreenPtr pScreenPriv; @@ -185,7 +184,7 @@ miDCCloseScreen (index, pScreen) tossPict (pScreenPriv->pTempPicture); #endif free ((void *) pScreenPriv); - return (*pScreen->CloseScreen) (index, pScreen); + return (*pScreen->CloseScreen) (pScreen); } static Bool diff --git a/nx-X11/programs/Xserver/mi/mioverlay.c b/nx-X11/programs/Xserver/mi/mioverlay.c index 796df6ebd7..c0d923a0f8 100644 --- a/nx-X11/programs/Xserver/mi/mioverlay.c +++ b/nx-X11/programs/Xserver/mi/mioverlay.c @@ -62,7 +62,7 @@ static Bool HasUnderlayChildren(WindowPtr); static void MarkUnderlayWindow(WindowPtr); static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr); -static Bool miOverlayCloseScreen(int, ScreenPtr); +static Bool miOverlayCloseScreen(ScreenPtr); static Bool miOverlayCreateWindow(WindowPtr); static Bool miOverlayDestroyWindow(WindowPtr); static Bool miOverlayUnrealizeWindow(WindowPtr); @@ -167,7 +167,7 @@ miInitOverlay( static Bool -miOverlayCloseScreen(int i, ScreenPtr pScreen) +miOverlayCloseScreen(ScreenPtr pScreen) { miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); @@ -179,7 +179,7 @@ miOverlayCloseScreen(int i, ScreenPtr pScreen) free(pScreenPriv); - return (*pScreen->CloseScreen)(i, pScreen); + return (*pScreen->CloseScreen)(pScreen); } diff --git a/nx-X11/programs/Xserver/mi/mipointer.c b/nx-X11/programs/Xserver/mi/mipointer.c index 01502c251c..dc5a4985d7 100644 --- a/nx-X11/programs/Xserver/mi/mipointer.c +++ b/nx-X11/programs/Xserver/mi/mipointer.c @@ -66,7 +66,7 @@ static void miPointerCursorLimits(ScreenPtr pScreen, CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox); static Bool miPointerSetCursorPosition(ScreenPtr pScreen, int x, int y, Bool generateEvent); -static Bool miPointerCloseScreen(int index, ScreenPtr pScreen); +static Bool miPointerCloseScreen(ScreenPtr pScreen); static void miPointerMove(ScreenPtr pScreen, int x, int y, unsigned long time); Bool @@ -132,8 +132,7 @@ miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate) } static Bool -miPointerCloseScreen (index, pScreen) - int index; +miPointerCloseScreen (pScreen) ScreenPtr pScreen; { SetupScreen(pScreen); @@ -144,7 +143,7 @@ miPointerCloseScreen (index, pScreen) miPointer.pSpriteScreen = 0; pScreen->CloseScreen = pScreenPriv->CloseScreen; free ((void *) pScreenPriv); - return (*pScreen->CloseScreen) (index, pScreen); + return (*pScreen->CloseScreen) (pScreen); } /* diff --git a/nx-X11/programs/Xserver/mi/miscrinit.c b/nx-X11/programs/Xserver/mi/miscrinit.c index 099ed6dcc1..e38284c501 100644 --- a/nx-X11/programs/Xserver/mi/miscrinit.c +++ b/nx-X11/programs/Xserver/mi/miscrinit.c @@ -128,8 +128,7 @@ miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, /*ARGSUSED*/ Bool -miCloseScreen (iScreen, pScreen) - int iScreen; +miCloseScreen (pScreen) ScreenPtr pScreen; { return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate)); diff --git a/nx-X11/programs/Xserver/mi/misprite.c b/nx-X11/programs/Xserver/mi/misprite.c index 592013d7fc..151de776d3 100644 --- a/nx-X11/programs/Xserver/mi/misprite.c +++ b/nx-X11/programs/Xserver/mi/misprite.c @@ -70,7 +70,7 @@ in this Software without prior written authorization from The Open Group. static int miSpriteScreenIndex; static unsigned long miSpriteGeneration = 0; -static Bool miSpriteCloseScreen(int i, ScreenPtr pScreen); +static Bool miSpriteCloseScreen(ScreenPtr pScreen); static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, unsigned int format, unsigned long planemask, char *pdstLine); @@ -248,8 +248,7 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs) */ static Bool -miSpriteCloseScreen (i, pScreen) - int i; +miSpriteCloseScreen (pScreen) ScreenPtr pScreen; { miSpriteScreenPtr pScreenPriv; @@ -270,7 +269,7 @@ miSpriteCloseScreen (i, pScreen) free ((void *) pScreenPriv); - return (*pScreen->CloseScreen) (i, pScreen); + return (*pScreen->CloseScreen) (pScreen); } static void diff --git a/nx-X11/programs/Xserver/miext/cw/cw.c b/nx-X11/programs/Xserver/miext/cw/cw.c index 774f0d0566..d9ca55f7e6 100644 --- a/nx-X11/programs/Xserver/miext/cw/cw.c +++ b/nx-X11/programs/Xserver/miext/cw/cw.c @@ -55,7 +55,7 @@ static unsigned long cwGeneration = 0; extern GCOps cwGCOps; static Bool -cwCloseScreen (int i, ScreenPtr pScreen); +cwCloseScreen (ScreenPtr pScreen); static void cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable); @@ -673,7 +673,7 @@ miDisableCompositeWrapper(ScreenPtr pScreen) } static Bool -cwCloseScreen (int i, ScreenPtr pScreen) +cwCloseScreen (ScreenPtr pScreen) { cwScreenPtr pScreenPriv; #ifdef RENDER @@ -697,5 +697,5 @@ cwCloseScreen (int i, ScreenPtr pScreen) free((void *)pScreenPriv); - return (*pScreen->CloseScreen)(i, pScreen); + return (*pScreen->CloseScreen)(pScreen); } diff --git a/nx-X11/programs/Xserver/miext/damage/damage.c b/nx-X11/programs/Xserver/miext/damage/damage.c index ca8128975f..348adcb659 100644 --- a/nx-X11/programs/Xserver/miext/damage/damage.c +++ b/nx-X11/programs/Xserver/miext/damage/damage.c @@ -1717,7 +1717,7 @@ damageDestroyWindow (WindowPtr pWindow) } static Bool -damageCloseScreen (int i, ScreenPtr pScreen) +damageCloseScreen (ScreenPtr pScreen) { damageScrPriv(pScreen); @@ -1729,7 +1729,7 @@ damageCloseScreen (int i, ScreenPtr pScreen) unwrap (pScrPriv, pScreen, CloseScreen); unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas); free (pScrPriv); - return (*pScreen->CloseScreen) (i, pScreen); + return (*pScreen->CloseScreen) (pScreen); } int damageScrPrivateIndex; diff --git a/nx-X11/programs/Xserver/randr/randr.c b/nx-X11/programs/Xserver/randr/randr.c index 9149c8a560..6b36c6f915 100644 --- a/nx-X11/programs/Xserver/randr/randr.c +++ b/nx-X11/programs/Xserver/randr/randr.c @@ -118,9 +118,6 @@ RRClientCallback(CallbackListPtr *list, void *closure, void *data) static Bool RRCloseScreen( -#ifdef NXAGENT_SERVER - int i, -#endif ScreenPtr pScreen) { rrScrPriv(pScreen); @@ -141,7 +138,7 @@ RRCloseScreen( free(pScrPriv->outputs); free(pScrPriv); RRNScreens -= 1; /* ok, one fewer screen with RandR running */ - return (*pScreen->CloseScreen) (i, pScreen); + return (*pScreen->CloseScreen) (pScreen); } static void diff --git a/nx-X11/programs/Xserver/render/animcur.c b/nx-X11/programs/Xserver/render/animcur.c index c5535050e5..5a84a1b411 100644 --- a/nx-X11/programs/Xserver/render/animcur.c +++ b/nx-X11/programs/Xserver/render/animcur.c @@ -111,7 +111,7 @@ AnimCurSetCursorPosition (ScreenPtr pScreen, Bool generateEvent); static Bool -AnimCurCloseScreen (int index, ScreenPtr pScreen) +AnimCurCloseScreen (ScreenPtr pScreen) { AnimCurScreenPtr as = GetAnimCurScreen(pScreen); Bool ret; @@ -127,10 +127,10 @@ AnimCurCloseScreen (int index, ScreenPtr pScreen) Unwrap(as, pScreen, UnrealizeCursor); Unwrap(as, pScreen, RecolorCursor); SetAnimCurScreen(pScreen,0); - ret = (*pScreen->CloseScreen) (index, pScreen); + ret = (*pScreen->CloseScreen) (pScreen); free (as); - if (index == 0) - AnimCurScreenPrivateIndex = -1; + if (screenInfo.numScreens == 0) + AnimCurScreenPrivateIndex = -1; return ret; } diff --git a/nx-X11/programs/Xserver/render/picture.c b/nx-X11/programs/Xserver/render/picture.c index 0d4c199692..4e7c02ecb0 100644 --- a/nx-X11/programs/Xserver/render/picture.c +++ b/nx-X11/programs/Xserver/render/picture.c @@ -127,14 +127,14 @@ PictureDestroyWindow (WindowPtr pWindow) } Bool -PictureCloseScreen (int index, ScreenPtr pScreen) +PictureCloseScreen (ScreenPtr pScreen) { PictureScreenPtr ps = GetPictureScreen(pScreen); Bool ret; int n; pScreen->CloseScreen = ps->CloseScreen; - ret = (*pScreen->CloseScreen) (index, pScreen); + ret = (*pScreen->CloseScreen) (pScreen); PictureResetFilters (pScreen); for (n = 0; n < ps->nformats; n++) if (ps->formats[n].type == PictTypeIndexed) diff --git a/nx-X11/programs/Xserver/render/picturestr.h b/nx-X11/programs/Xserver/render/picturestr.h index 27c36dc9c0..f5c367bb42 100644 --- a/nx-X11/programs/Xserver/render/picturestr.h +++ b/nx-X11/programs/Xserver/render/picturestr.h @@ -410,7 +410,7 @@ Bool PictureDestroyWindow (WindowPtr pWindow); Bool -PictureCloseScreen (int Index, ScreenPtr pScreen); +PictureCloseScreen (ScreenPtr pScreen); void PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef); diff --git a/nx-X11/programs/Xserver/xfixes/cursor.c b/nx-X11/programs/Xserver/xfixes/cursor.c index 441c4d0b22..c6d737473c 100644 --- a/nx-X11/programs/Xserver/xfixes/cursor.c +++ b/nx-X11/programs/Xserver/xfixes/cursor.c @@ -114,17 +114,17 @@ CursorDisplayCursor (ScreenPtr pScreen, } static Bool -CursorCloseScreen (int index, ScreenPtr pScreen) +CursorCloseScreen (ScreenPtr pScreen) { CursorScreenPtr cs = GetCursorScreen (pScreen); Bool ret; Unwrap (cs, pScreen, CloseScreen); Unwrap (cs, pScreen, DisplayCursor); - ret = (*pScreen->CloseScreen) (index, pScreen); + ret = (*pScreen->CloseScreen) (pScreen); free (cs); - if (index == 0) - CursorScreenPrivateIndex = -1; + if (screenInfo.numScreens == 0) + CursorScreenPrivateIndex = -1; return ret; } From c806b1a767a359cd11874e8fb09148ca3cc23bb3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 11 Mar 2017 01:34:14 +0100 Subject: [PATCH 26/33] dix: make Create/Free scratch pixmaps take a ScreenPtr commit 1f0e8bd5eb1a5539689cfc4f5a6b86b530907ec5 Author: Dave Airlie Date: Tue Jun 5 13:22:18 2012 +0100 api: rework the X server driver API to avoid global arrays. This is a squash merge containing all the API changes, as well as the video ABI bump. Its been squashed to make bisection easier. Full patch log below: [...] commit 37c3ae3e6cd4f3dedc72f371096d6743f8f99df3 Author: Dave Airlie Date: Wed May 23 15:09:12 2012 +0100 dix: make Create/Free scratch pixmaps take a ScreenPtr While technically an API/ABI change I doubt anyone uses it, but it helps in splitting screens up. Reviewed-by: Keith Packard Signed-off-by: Dave Airlie [...] Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/gc.c | 16 ++++------------ nx-X11/programs/Xserver/dix/main.c | 17 +++++++++-------- nx-X11/programs/Xserver/dix/pixmap.c | 8 ++++---- nx-X11/programs/Xserver/include/gc.h | 8 ++++---- nx-X11/programs/Xserver/include/pixmap.h | 4 ++-- 5 files changed, 23 insertions(+), 30 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/gc.c b/nx-X11/programs/Xserver/dix/gc.c index d40334f5f5..10a092019b 100644 --- a/nx-X11/programs/Xserver/dix/gc.c +++ b/nx-X11/programs/Xserver/dix/gc.c @@ -984,13 +984,11 @@ CreateScratchGC(ScreenPtr pScreen, unsigned depth) } void -FreeGCperDepth(int screenNum) +FreeGCperDepth(ScreenPtr pScreen) { register int i; - register ScreenPtr pScreen; GCPtr *ppGC; - pScreen = screenInfo.screens[screenNum]; ppGC = pScreen->GCperDepth; for (i = 0; i <= pScreen->numDepths; i++) @@ -1000,14 +998,12 @@ FreeGCperDepth(int screenNum) Bool -CreateGCperDepth(int screenNum) +CreateGCperDepth(ScreenPtr pScreen) { register int i; - register ScreenPtr pScreen; DepthPtr pDepth; GCPtr *ppGC; - pScreen = screenInfo.screens[screenNum]; pScreen->rgf = 0; ppGC = pScreen->GCperDepth; /* do depth 1 separately because it's not included in list */ @@ -1033,16 +1029,13 @@ CreateGCperDepth(int screenNum) } Bool -CreateDefaultStipple(int screenNum) +CreateDefaultStipple(ScreenPtr pScreen) { - register ScreenPtr pScreen; XID tmpval[3]; xRectangle rect; CARD16 w, h; GCPtr pgcScratch; - pScreen = screenInfo.screens[screenNum]; - w = 16; h = 16; (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen); @@ -1070,9 +1063,8 @@ CreateDefaultStipple(int screenNum) } void -FreeDefaultStipple(int screenNum) +FreeDefaultStipple(ScreenPtr pScreen) { - ScreenPtr pScreen = screenInfo.screens[screenNum]; (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]); } diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 82eab4b615..798de48d2a 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -276,14 +276,14 @@ main(int argc, char *argv[], char *envp[]) for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; - if (!CreateScratchPixmapsForScreen(i)) + if (!CreateScratchPixmapsForScreen(pScreen)) FatalError("failed to create scratch pixmaps"); if (pScreen->CreateScreenResources && !(*pScreen->CreateScreenResources)(pScreen)) FatalError("failed to create screen resources"); - if (!CreateGCperDepth(i)) + if (!CreateGCperDepth(pScreen)) FatalError("failed to create scratch GCs"); - if (!CreateDefaultStipple(i)) + if (!CreateDefaultStipple(pScreen)) FatalError("failed to create default stipple"); if (!CreateRootWindow(pScreen)) FatalError("failed to create root window"); @@ -365,11 +365,12 @@ main(int argc, char *argv[], char *envp[]) for (i = screenInfo.numScreens - 1; i >= 0; i--) { - FreeScratchPixmapsForScreen(i); - FreeGCperDepth(i); - FreeDefaultStipple(i); - (* screenInfo.screens[i]->CloseScreen)(screenInfo.screens[i]); - FreeScreen(screenInfo.screens[i]); + ScreenPtr pScreen = screenInfo.screens[i]; + FreeScratchPixmapsForScreen(pScreen); + FreeGCperDepth(pScreen); + FreeDefaultStipple(pScreen); + (* pScreen->CloseScreen)(pScreen); + FreeScreen(pScreen); screenInfo.numScreens = i; } FreeFonts(); diff --git a/nx-X11/programs/Xserver/dix/pixmap.c b/nx-X11/programs/Xserver/dix/pixmap.c index 747120b48e..fb306e927b 100644 --- a/nx-X11/programs/Xserver/dix/pixmap.c +++ b/nx-X11/programs/Xserver/dix/pixmap.c @@ -89,18 +89,18 @@ FreeScratchPixmapHeader(PixmapPtr pPixmap) Bool -CreateScratchPixmapsForScreen(int scrnum) +CreateScratchPixmapsForScreen(ScreenPtr pScreen) { /* let it be created on first use */ - screenInfo.screens[scrnum]->pScratchPixmap = NULL; + pScreen->pScratchPixmap = NULL; return TRUE; } void -FreeScratchPixmapsForScreen(int scrnum) +FreeScratchPixmapsForScreen(ScreenPtr pScreen) { - FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap); + FreeScratchPixmapHeader(pScreen->pScratchPixmap); } diff --git a/nx-X11/programs/Xserver/include/gc.h b/nx-X11/programs/Xserver/include/gc.h index 75a38617ef..c65b030333 100644 --- a/nx-X11/programs/Xserver/include/gc.h +++ b/nx-X11/programs/Xserver/include/gc.h @@ -150,16 +150,16 @@ extern GCPtr CreateScratchGC( unsigned /*depth*/); extern void FreeGCperDepth( - int /*screenNum*/); + ScreenPtr /*pScreen*/); extern Bool CreateGCperDepth( - int /*screenNum*/); + ScreenPtr /*pScreen*/); extern Bool CreateDefaultStipple( - int /*screenNum*/); + ScreenPtr /*pScreen*/); extern void FreeDefaultStipple( - int /*screenNum*/); + ScreenPtr /*pScreen*/); extern int SetDashes( GCPtr /*pGC*/, diff --git a/nx-X11/programs/Xserver/include/pixmap.h b/nx-X11/programs/Xserver/include/pixmap.h index 22e1ce7bdf..aee4fd7069 100644 --- a/nx-X11/programs/Xserver/include/pixmap.h +++ b/nx-X11/programs/Xserver/include/pixmap.h @@ -97,10 +97,10 @@ extern void FreeScratchPixmapHeader( PixmapPtr /*pPixmap*/); extern Bool CreateScratchPixmapsForScreen( - int /*scrnum*/); + ScreenPtr /*pScreen*/); extern void FreeScratchPixmapsForScreen( - int /*scrnum*/); + ScreenPtr /*pScreen*/); extern PixmapPtr AllocatePixmap( ScreenPtr /*pScreen*/, From a414f74fbacbef44b6fdccc33461a9d70d0c8fd7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 10 Mar 2017 17:03:11 +0100 Subject: [PATCH 27/33] dix: introduce gpu screens. (v5) Backports from X.org: commit 9d179818293b466ec6f1777f0b792e1fbbeb318c Author: Dave Airlie Date: Tue Jun 5 17:09:38 2012 +0100 dix: introduce gpu screens. (v5) This patch introduces gpu screens into screenInfo. It adds interfaces for adding and removing gpu screens, along with adding private fixup, block handler support, and scratch pixmap init. GPU screens have a myNum that is offset by GPU_SCREEN_OFFSET (256), this is used for logging etc. RemoveGPUScreen isn't used until "xfree86: add platform bus hotplug support". v2: no glyph pictures for GPU screens for now. v3: introduce MAXGPUSCREENS, fix return value check v4: fixup myNum when renumbering screens (ajax) v5: drop cursor privates for now. Reviewed-by: Keith Packard Signed-off-by: Dave Airlie commit 288b87e42cbb5db34cda848143655e84af8455da Author: Keith Packard Date: Tue Aug 7 17:49:47 2012 -0700 Close GPU screens before core screens This should make cleaning up the GPU screens easier as the core screens they are associated with will still be around. Signed-off-by: Keith Packard Reviewed-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/dispatch.c | 74 +++++++++++++++++++- nx-X11/programs/Xserver/dix/dixutils.c | 8 +++ nx-X11/programs/Xserver/dix/main.c | 16 +++++ nx-X11/programs/Xserver/include/misc.h | 4 ++ nx-X11/programs/Xserver/include/screenint.h | 9 +++ nx-X11/programs/Xserver/include/scrnintstr.h | 4 ++ 6 files changed, 113 insertions(+), 2 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 78e14949ff..165a5e5aa7 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -4033,7 +4033,7 @@ static int indexForScanlinePad[ 65 ] = { #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif -static int init_screen(ScreenPtr pScreen, int i) +static int init_screen(ScreenPtr pScreen, int i, Bool gpu) { int scanlinepad, format, depth, bitsPerPixel, j, k; #ifdef DEBUG @@ -4041,6 +4041,10 @@ static int init_screen(ScreenPtr pScreen, int i) #endif /* DEBUG */ pScreen->myNum = i; + if (gpu) { + pScreen->myNum += GPU_SCREEN_OFFSET; + pScreen->isGPU = TRUE; + } pScreen->WindowPrivateLen = 0; pScreen->WindowPrivateSizes = (unsigned *)NULL; pScreen->totalWindowSize = @@ -4133,7 +4137,7 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , if (!pScreen->devPrivates && screenPrivateCount) return -1; - ret = init_screen(pScreen, i); + ret = init_screen(pScreen, i, FALSE); if (ret != 0) { free(pScreen); return ret; @@ -4170,3 +4174,69 @@ FreeScreen(ScreenPtr pScreen) free(pScreen->devPrivates); free(pScreen); } + + +int +AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , + int /*argc */ , + char ** /*argv */ + ), + int argc, char **argv) +{ + int i; + ScreenPtr pScreen; + Bool ret; + + i = screenInfo.numGPUScreens; + if (i == MAXGPUSCREENS) + return -1; + + pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); + if (!pScreen) + return -1; + + ret = init_screen(pScreen, i, TRUE); + if (ret != 0) { + free(pScreen); + return ret; + } + + /* This is where screen specific stuff gets initialized. Load the + screen structure, call the hardware, whatever. + This is also where the default colormap should be allocated and + also pixel values for blackPixel, whitePixel, and the cursor + Note that InitScreen is NOT allowed to modify argc, argv, or + any of the strings pointed to by argv. They may be passed to + multiple screens. + */ + screenInfo.gpuscreens[i] = pScreen; + screenInfo.numGPUScreens++; + if (!(*pfnInit) (pScreen, argc, argv)) { + dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); + free(pScreen); + screenInfo.numGPUScreens--; + return -1; + } + + update_desktop_dimensions(); + + return i; +} + +void +RemoveGPUScreen(ScreenPtr pScreen) +{ + int idx, j; + if (!pScreen->isGPU) + return; + + idx = pScreen->myNum - GPU_SCREEN_OFFSET; + for (j = idx; j < screenInfo.numGPUScreens - 1; j++) { + screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1]; + screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET; + } + screenInfo.numGPUScreens--; + + free(pScreen); + +} diff --git a/nx-X11/programs/Xserver/dix/dixutils.c b/nx-X11/programs/Xserver/dix/dixutils.c index 3ccc90d718..4a62ec8942 100644 --- a/nx-X11/programs/Xserver/dix/dixutils.c +++ b/nx-X11/programs/Xserver/dix/dixutils.c @@ -399,6 +399,10 @@ BlockHandler(void * pTimeout, void * pReadmask) (* screenInfo.screens[i]->BlockHandler)(i, screenInfo.screens[i]->blockData, pTimeout, pReadmask); + for (i = 0; i < screenInfo.numGPUScreens; i++) + (*screenInfo.gpuscreens[i]->BlockHandler) (i, + screenInfo.gpuscreens[i]->blockData, + pTimeout, pReadmask); for (i = 0; i < numHandlers; i++) (*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout, pReadmask); @@ -436,6 +440,10 @@ WakeupHandler(int result, void * pReadmask) (* screenInfo.screens[i]->WakeupHandler)(i, screenInfo.screens[i]->wakeupData, result, pReadmask); + for (i = 0; i < screenInfo.numGPUScreens; i++) + (*screenInfo.gpuscreens[i]->WakeupHandler) (i, + screenInfo.gpuscreens[i]->wakeupData, + result, pReadmask); if (handlerDeleted) { for (i = 0; i < numHandlers;) diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 798de48d2a..0ed12b828b 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -273,6 +273,13 @@ main(int argc, char *argv[], char *envp[]) InitExtensions(argc, argv); if (!InitClientPrivates(serverClient)) FatalError("failed to allocate serverClient devprivates"); + + for (i = 0; i < screenInfo.numGPUScreens; i++) { + ScreenPtr pScreen = screenInfo.gpuscreens[i]; + if (!CreateScratchPixmapsForScreen(pScreen)) + FatalError("failed to create scratch pixmaps"); + } + for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; @@ -363,6 +370,14 @@ main(int argc, char *argv[], char *envp[]) CloseDownDevices(); CloseDownEvents(); + for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) { + ScreenPtr pScreen = screenInfo.gpuscreens[i]; + FreeScratchPixmapsForScreen(pScreen); + (*pScreen->CloseScreen) (pScreen); + FreeScreen(pScreen); + screenInfo.numGPUScreens = i; + } + for (i = screenInfo.numScreens - 1; i >= 0; i--) { ScreenPtr pScreen = screenInfo.screens[i]; @@ -373,6 +388,7 @@ main(int argc, char *argv[], char *envp[]) FreeScreen(pScreen); screenInfo.numScreens = i; } + FreeFonts(); #ifdef DPMSExtension diff --git a/nx-X11/programs/Xserver/include/misc.h b/nx-X11/programs/Xserver/include/misc.h index 27137cd504..c520e9183c 100644 --- a/nx-X11/programs/Xserver/include/misc.h +++ b/nx-X11/programs/Xserver/include/misc.h @@ -103,11 +103,15 @@ extern unsigned long serverGeneration; #ifndef MAXSCREENS #define MAXSCREENS 16 #endif +#ifndef MAXGPUSCREENS +#define MAXGPUSCREENS 16 +#endif #define MAXCLIENTS 256 #define MAXDITS 1 #define MAXEXTENSIONS 128 #define MAXFORMATS 8 #define MAXVISUALS_PER_SCREEN 50 +#define GPU_SCREEN_OFFSET 256 typedef unsigned long PIXEL; typedef unsigned long ATOM; diff --git a/nx-X11/programs/Xserver/include/screenint.h b/nx-X11/programs/Xserver/include/screenint.h index abaa6f85b1..8b39e1fbdc 100644 --- a/nx-X11/programs/Xserver/include/screenint.h +++ b/nx-X11/programs/Xserver/include/screenint.h @@ -85,6 +85,15 @@ extern int AddScreen( int /*argc*/, char** /*argv*/); + +extern int AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , + int /*argc */ , + char ** /*argv */ + ), + int argc, char **argv); + +extern void RemoveGPUScreen(ScreenPtr pScreen); + #ifdef PIXPRIV extern void ResetPixmapPrivates(void); diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index 99a2818765..f64d1bdb78 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -736,6 +736,8 @@ typedef struct _Screen { ChangeBorderWidthProcPtr ChangeBorderWidth; MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; + Bool isGPU; + ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap; SharePixmapBackingProcPtr SharePixmapBacking; @@ -760,6 +762,8 @@ typedef struct _ScreenInfo { int arraySize; int numScreens; ScreenPtr screens[MAXSCREENS]; + int numGPUScreens; + ScreenPtr gpuscreens[MAXGPUSCREENS]; int numVideoScreens; } ScreenInfo; From e2b323ee84f0c03dc3ed3f299b59f4176858e56d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 11 Mar 2017 01:41:11 +0100 Subject: [PATCH 28/33] dix: add unattached list for attaching screens to initially. (v1.1) commit 4caad34c932115dc0a9fd9c2995ebb2d38b9359c Author: Dave Airlie Date: Wed Jun 13 14:27:42 2012 +0100 dix: add unattached list for attaching screens to initially. (v1.1) This list is meant for attaching unbound gpu screens to initially, before the client side rebinds them. v1.1: add another assert in the add path. Reviewed-by: Keith Packard Reviewed-by: Adam Jackson Signed-off-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/extras/Mesa/include/GL/xmesa_xf86.h | 2 +- nx-X11/programs/Xserver/dix/dispatch.c | 19 +++++++++++++++++++ nx-X11/programs/Xserver/include/screenint.h | 5 +++++ nx-X11/programs/Xserver/include/scrnintstr.h | 6 ++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/nx-X11/extras/Mesa/include/GL/xmesa_xf86.h b/nx-X11/extras/Mesa/include/GL/xmesa_xf86.h index 63a8e57dbc..83094f341a 100644 --- a/nx-X11/extras/Mesa/include/GL/xmesa_xf86.h +++ b/nx-X11/extras/Mesa/include/GL/xmesa_xf86.h @@ -130,7 +130,7 @@ do { \ /* CreatePixmap returns a PixmapPtr; so, it cannot be inside braces */ #define XMesaCreatePixmap(__d,__b,__w,__h,__depth) \ - (*__d->CreatePixmap)(__d, __w, __h, __depth) + (*__d->CreatePixmap)(__d, __w, __h, __depth, 0) #define XMesaFreePixmap(__d,__b) \ (*__d->DestroyPixmap)(__b) diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 165a5e5aa7..84bf0ea088 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -4061,6 +4061,8 @@ static int init_screen(ScreenPtr pScreen, int i, Bool gpu) pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ pScreen->CreateScreenResources = 0; + xorg_list_init(&pScreen->unattached_list); + #ifdef DEBUG for (jNI = &pScreen->QueryBestSize; jNI < (void (**) ()) &pScreen->SendGraphicsExpose; @@ -4240,3 +4242,20 @@ RemoveGPUScreen(ScreenPtr pScreen) free(pScreen); } + +void +AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new) +{ + assert(new->isGPU); + assert(!new->current_master); + xorg_list_add(&new->unattached_head, &pScreen->unattached_list); + new->current_master = pScreen; +} + +void +DetachUnboundGPU(ScreenPtr slave) +{ + assert(slave->isGPU); + xorg_list_del(&slave->unattached_head); + slave->current_master = NULL; +} diff --git a/nx-X11/programs/Xserver/include/screenint.h b/nx-X11/programs/Xserver/include/screenint.h index 8b39e1fbdc..54fe0ab453 100644 --- a/nx-X11/programs/Xserver/include/screenint.h +++ b/nx-X11/programs/Xserver/include/screenint.h @@ -94,6 +94,11 @@ extern int AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , extern void RemoveGPUScreen(ScreenPtr pScreen); +extern void +AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new); +extern void +DetachUnboundGPU(ScreenPtr unbound); + #ifdef PIXPRIV extern void ResetPixmapPrivates(void); diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index f64d1bdb78..f0e8d1746b 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -56,6 +56,7 @@ SOFTWARE. #include "validate.h" #include #include "dix.h" +#include "list.h" typedef struct _PixmapFormat { unsigned char depth; @@ -738,6 +739,11 @@ typedef struct _Screen { Bool isGPU; + struct xorg_list unattached_list; + struct xorg_list unattached_head; + + ScreenPtr current_master; + ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap; SharePixmapBackingProcPtr SharePixmapBacking; From 3cacd47d1e987a0cf0b24d93744cec63e1a4b399 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 10 Mar 2017 15:40:45 +0100 Subject: [PATCH 29/33] randr: fixup+complete scanout pixmap support by adapting the dix. Done by partially backporting the below X.org commit and unifdef'ing the scanout pixmap support in the already plainly copied in RandR 1.5 code: commit f2da2c12042d3447b1c954e7301632d174a08b4f Author: Dave Airlie Date: Wed Jun 20 12:37:12 2012 +0100 randr: add initial scanout pixmap support (v3) When randr notices a crtc configuration request for a slave device, it checks if the slave allocated pixmap exists and is suitable, if not it allocates a new shared pixmap from the master, shares it to the slave, and starts the master tracking damage to it, to keep it updated from the current front pixmap. If the resize means the crtc is no longer used it will destroy the slave pixmap. This adds the concept of a scanout_pixmap to the randr_crtc object, and also adds a master pixmap pointer to the pixmap object, along with defining some pixmap helper functions for getting pixmap box/regions. v2: split out pixmap sharing to a separate function. v3: update for void * Reviewed-by: Keith Packard Reviewed-by: Adam Jackson Signed-off-by: Dave Airlie Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/pixmap.c | 30 +++++++++++++++++++++ nx-X11/programs/Xserver/include/pixmap.h | 5 ++++ nx-X11/programs/Xserver/include/pixmapstr.h | 22 +++++++++++++++ nx-X11/programs/Xserver/randr/rrcrtc.c | 3 --- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/pixmap.c b/nx-X11/programs/Xserver/dix/pixmap.c index fb306e927b..1235d42625 100644 --- a/nx-X11/programs/Xserver/dix/pixmap.c +++ b/nx-X11/programs/Xserver/dix/pixmap.c @@ -148,3 +148,33 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize) #endif return pPixmap; } + + +PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave) +{ + PixmapPtr spix; + int ret; + void *handle; + ScreenPtr master = pixmap->drawable.pScreen; + int depth = pixmap->drawable.depth; + + ret = master->SharePixmapBacking(pixmap, slave, &handle); + if (ret == FALSE) + return NULL; + + spix = slave->CreatePixmap(slave, 0, 0, depth, + CREATE_PIXMAP_USAGE_SHARED); + slave->ModifyPixmapHeader(spix, pixmap->drawable.width, + pixmap->drawable.height, depth, 0, + pixmap->devKind, NULL); + + spix->master_pixmap = pixmap; + + ret = slave->SetSharedPixmapBacking(spix, handle); + if (ret == FALSE) { + slave->DestroyPixmap(spix); + return NULL; + } + + return spix; +} diff --git a/nx-X11/programs/Xserver/include/pixmap.h b/nx-X11/programs/Xserver/include/pixmap.h index aee4fd7069..1825f6ef76 100644 --- a/nx-X11/programs/Xserver/include/pixmap.h +++ b/nx-X11/programs/Xserver/include/pixmap.h @@ -106,4 +106,9 @@ extern PixmapPtr AllocatePixmap( ScreenPtr /*pScreen*/, int /*pixDataSize*/); +extern PixmapPtr +PixmapShareToSlave( + PixmapPtr /*pixmap*/, + ScreenPtr /*slave*/); + #endif /* PIXMAP_H */ diff --git a/nx-X11/programs/Xserver/include/pixmapstr.h b/nx-X11/programs/Xserver/include/pixmapstr.h index 82b96d456f..7971ea11fc 100644 --- a/nx-X11/programs/Xserver/include/pixmapstr.h +++ b/nx-X11/programs/Xserver/include/pixmapstr.h @@ -83,6 +83,28 @@ typedef struct _Pixmap { short screen_y; #endif unsigned usage_hint; /* see CREATE_PIXMAP_USAGE_* */ + + PixmapPtr master_pixmap;/* pointer to master copy of pixmap for pixmap sharing */ } PixmapRec; +static inline void +PixmapBox(BoxPtr box, PixmapPtr pixmap) +{ + box->x1 = 0; + box->x2 = pixmap->drawable.width; + + box->y1 = 0; + box->y2 = pixmap->drawable.height; +} + + +static inline void +PixmapRegionInit(RegionPtr region, PixmapPtr pixmap) +{ + BoxRec box; + + PixmapBox(&box, pixmap); + RegionInit(region, &box, 1); +} + #endif /* PIXMAPSTRUCT_H */ diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index 54758bbdca..da16d011db 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -420,7 +420,6 @@ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc) RRCrtcChanged(crtc, TRUE); } -#ifndef NXAGENT_SERVER static PixmapPtr rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master, int width, int height, int depth, @@ -642,7 +641,6 @@ RRCrtcSet(RRCrtcPtr crtc, ret = TRUE; } else { -#ifndef NXAGENT_SERVER if (pScreen->isGPU) { ScreenPtr master = pScreen->current_master; int width = 0, height = 0; @@ -660,7 +658,6 @@ RRCrtcSet(RRCrtcPtr crtc, ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation); } } -#endif #if RANDR_12_INTERFACE if (pScrPriv->rrCrtcSet) { ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, From c4cead5d91a2c5ff51ba1db7176195e175d713e3 Mon Sep 17 00:00:00 2001 From: Alex Goins Date: Fri, 10 Mar 2017 14:45:45 +0100 Subject: [PATCH 30/33] randr(/xf86): Add PRIME Synchronization / Double Buffer Backport from X.org: commit 1bdbc7e764ed7bf7c1ae46287dec368aa7c7e80d Author: Alex Goins Date: Thu Jun 16 20:06:47 2016 -0700 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 Signed-off-by: Alex Goins Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/randrstr.h | 1 + nx-X11/programs/Xserver/randr/rrcrtc.c | 133 ++++++++++++++++++----- 2 files changed, 105 insertions(+), 29 deletions(-) diff --git a/nx-X11/programs/Xserver/randr/randrstr.h b/nx-X11/programs/Xserver/randr/randrstr.h index 4b497f82dc..1d2a00247b 100644 --- a/nx-X11/programs/Xserver/randr/randrstr.h +++ b/nx-X11/programs/Xserver/randr/randrstr.h @@ -135,6 +135,7 @@ struct _rrCrtc { struct pict_f_transform f_inverse; PixmapPtr scanout_pixmap; + PixmapPtr scanout_pixmap_back; }; struct _rrOutput { diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index da16d011db..7d009b7ab0 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -392,9 +392,6 @@ rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) { ScreenPtr master = crtc->pScreen->current_master; if (master && pPixmap->master_pixmap) { - PixmapPtr mscreenpix = master->GetScreenPixmap(master); - - master->StopPixmapTracking(mscreenpix, pPixmap); /* * Unref the pixmap twice: once for the original reference, and once * for the reference implicitly added by PixmapShareToSlave. @@ -412,11 +409,29 @@ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc) { rrScrPriv(crtc->pScreen); - pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); if (crtc->scanout_pixmap) { + ScreenPtr master = crtc->pScreen->current_master; + PixmapPtr mscreenpix = master->GetScreenPixmap(master); + + if (crtc->scanout_pixmap_back) { + pScrPriv->rrDisableSharedPixmapFlipping(crtc); + + master->StopFlippingPixmapTracking(mscreenpix, + crtc->scanout_pixmap, + crtc->scanout_pixmap_back); + + rrDestroySharedPixmap(crtc, crtc->scanout_pixmap_back); + crtc->scanout_pixmap_back = NULL; + } + else { + pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); + master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap); + } + rrDestroySharedPixmap(crtc, crtc->scanout_pixmap); + crtc->scanout_pixmap = NULL; } - crtc->scanout_pixmap = NULL; + RRCrtcChanged(crtc, TRUE); } @@ -425,9 +440,7 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master, int width, int height, int depth, int x, int y, Rotation rotation) { - Bool ret; PixmapPtr mpix, spix; - rrScrPriv(crtc->pScreen); mpix = master->CreatePixmap(master, width, height, depth, CREATE_PIXMAP_USAGE_SHARED); @@ -440,13 +453,6 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master, return NULL; } - ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix); - if (ret == FALSE) { - rrDestroySharedPixmap(crtc, spix); - ErrorF("randr: failed to set shadow slave pixmap\n"); - return NULL; - } - return spix; } @@ -455,17 +461,31 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, int x, int y, Rotation rotation) { ScreenPtr master = crtc->pScreen->current_master; + rrScrPrivPtr pMasterScrPriv = rrGetScrPriv(master); + rrScrPrivPtr pSlaveScrPriv = rrGetScrPriv(crtc->pScreen); + int depth; PixmapPtr mscreenpix; - PixmapPtr spix; - - /* create a pixmap on the master screen, - then get a shared handle for it - create a shared pixmap on the slave screen using the handle - set the master screen to do dirty updates to the shared pixmap - from the screen pixmap. - set slave screen to scanout shared linear pixmap - */ + PixmapPtr spix_front; + + /* Create a pixmap on the master screen, then get a shared handle for it. + Create a shared pixmap on the slave screen using the handle. + + If sync == FALSE -- + Set slave screen to scanout shared linear pixmap. + Set the master screen to do dirty updates to the shared pixmap + from the screen pixmap on its own accord. + + If sync == TRUE -- + If any of the below steps fail, clean up and fall back to sync == FALSE. + Create another shared pixmap on the slave screen using the handle. + Set slave screen to prepare for scanout and flipping between shared + linear pixmaps. + Set the master screen to do dirty updates to the shared pixmaps from the + screen pixmap when prompted to by us or the slave. + Prompt the master to do a dirty update on the first shared pixmap, then + defer to the slave. + */ mscreenpix = master->GetScreenPixmap(master); depth = mscreenpix->drawable.depth; @@ -477,16 +497,65 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, return TRUE; } - spix = rrCreateSharedPixmap(crtc, master, - width, height, depth, - x, y, rotation); - if (spix == NULL) { + spix_front = rrCreateSharedPixmap(crtc, master, + width, height, depth, + x, y, rotation); + if (spix_front == NULL) { + return FALSE; + } + + /* Both source and sink must support required ABI funcs for flipping */ + if (pSlaveScrPriv->rrEnableSharedPixmapFlipping && + pSlaveScrPriv->rrDisableSharedPixmapFlipping && + pMasterScrPriv->rrStartFlippingPixmapTracking && + master->PresentSharedPixmap && + master->StopFlippingPixmapTracking) { + + PixmapPtr spix_back = rrCreateSharedPixmap(crtc, master, + width, height, depth, + x, y, rotation); + if (spix_back == NULL) + goto fail; + + if (!pSlaveScrPriv->rrEnableSharedPixmapFlipping(crtc, + spix_front, spix_back)) + goto fail; + + crtc->scanout_pixmap = spix_front; + crtc->scanout_pixmap_back = spix_back; + + if (!pMasterScrPriv->rrStartFlippingPixmapTracking(crtc, mscreenpix, + spix_front, + spix_back, + x, y, 0, 0, + rotation)) { + pSlaveScrPriv->rrDisableSharedPixmapFlipping(crtc); + goto fail; + } + + master->PresentSharedPixmap(spix_front); + + return TRUE; + +fail: /* If flipping funcs fail, just fall back to unsynchronized */ + if (spix_back) + rrDestroySharedPixmap(crtc, spix_back); + + crtc->scanout_pixmap = NULL; + crtc->scanout_pixmap_back = NULL; + } + + ErrorF("randr: falling back to unsynchronized pixmap sharing\n"); + + if (!pSlaveScrPriv->rrCrtcSetScanoutPixmap(crtc, spix_front)) { + rrDestroySharedPixmap(crtc, spix_front); + ErrorF("randr: failed to set shadow slave pixmap\n"); return FALSE; } + crtc->scanout_pixmap = spix_front; - crtc->scanout_pixmap = spix; + master->StartPixmapTracking(mscreenpix, spix_front, x, y, 0, 0, rotation); - master->StartPixmapTracking(mscreenpix, spix, x, y, 0, 0, rotation); return TRUE; } @@ -1836,6 +1905,12 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable) if (!crtc->scanout_pixmap && !enable) continue; + /* not supported with double buffering, needs ABI change for 2 ppix */ + if (crtc->scanout_pixmap_back) { + ret = FALSE; + continue; + } + size_fits = (crtc->mode && crtc->x == pDrawable->x && crtc->y == pDrawable->y && From b7353462604bddc029bab76a6ebb7ac58a4a6d13 Mon Sep 17 00:00:00 2001 From: Alex Goins Date: Fri, 10 Mar 2017 14:32:36 +0100 Subject: [PATCH 31/33] xf86: Add PRIME flipping functions to Screen commit b601f96a5915a2c486b389483b291797e6fdf617 Author: Alex Goins Date: Thu Jun 16 20:06:46 2016 -0700 xf86: Add PRIME flipping functions to Screen Adds typedefs for (*RRStartFlippingPixmapTrackingProcPtr), (*RREnableSharedPixmapFlippingProcPtr), and (*RRDisableSharedPixmapFlippingProcPtr) in randrstr.h. Adds typedefs for (*PresentSharedPixmapProcPtr), (*SharedPixmapNotifyDamageProcPtr), (*RequestSharedPixmapNotifyDamageProcPtr), and (*StopFlippingPixmapTrackingProcPtr) in scrnintstr.h. Adds RR(Enable/Disable)SharedPixmapFlipping, and RRStartFlippingPixmapTracking to rrScrnPrivRec. Adds StopFlippingPixmapTracking, PresentSharedPixmap, SharedPixmapNotifyDamage, and RequestSharedPixmapNotifyDamage to ScreenRec. rrScrnPrivRec used for functions that use RandR-private data types, and ScreenRec used for the rest. RREnableSharedPixmapFlipping will allow the sink driver to setup for flipping between two shared pixmaps. RRDisableSharedPixmapFlipping will allow the sink driver to do teardown associated with flipping between two shared pixmaps. (RRStart/Stop)FlippingPixmapTracking are merely the double-buffered equivalents of (Start/Stop)PixmapTracking, allowing the source driver to do whatever setup and teardown necessary for presenting on the two shared pixmaps. PresentSharedPixmap is a function exposed by the source driver for the X server or sink driver to call to request a present on a given shared pixmap. This way, presents can be driven by the sink's vblank instead of a timer or similar mechanism. SharedPixmapNotifyDamage and RequestSharedPixmapNotifyDamage are OPTIONAL (even for double-buffered PRIME) functions exposed by the sink driver and the source driver, respectively. By calling master->RequestSharedPixmapNotifyDamage(ppix), the sink driver can request for the source driver to call slave->SharedPixmapNotifyDamage(ppix) in response to damage on the master screen pixmap tracked by ppix. v1: Initial commit v2: Rename PresentTrackedFlippingPixmap to PresentSharedPixmap Add SharedPixmapNotifyDamage / RequestSharedPixmapNotifyDamage v3: Add RRCrtcPtr as a parameter to StartFlippingPixmapTracking Move functions that use RandR-private data types to rrScrnPrivRec. v4: Unchanged v5: Add front and back parameters to RREnableSharedPixmapFlippingProcPtr v6: Rebase onto ToT v7: Unchanged Reviewed-by: Dave Airlie Signed-off-by: Alex Goins Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/scrnintstr.h | 14 ++++++++++++++ nx-X11/programs/Xserver/randr/randrstr.h | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index f0e8d1746b..5f754fbff3 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -537,6 +537,20 @@ typedef void (*ConstrainCursorHarderProcPtr)( int *, /*x*/ int * /*y*/); +typedef Bool (*PresentSharedPixmapProcPtr)( + PixmapPtr /* */); + +typedef Bool (*RequestSharedPixmapNotifyDamageProcPtr)( + PixmapPtr /* */); + +typedef Bool (*StopFlippingPixmapTrackingProcPtr)( + PixmapPtr, /* */ + PixmapPtr, /* */ + PixmapPtr /* */); + +typedef Bool (*SharedPixmapNotifyDamageProcPtr)( + PixmapPtr /* */); + typedef Bool (*ReplaceScanoutPixmapProcPtr)( DrawablePtr, /*pDrawable*/ PixmapPtr, /*pPixmap*/ diff --git a/nx-X11/programs/Xserver/randr/randrstr.h b/nx-X11/programs/Xserver/randr/randrstr.h index 1d2a00247b..63d5ffa55e 100644 --- a/nx-X11/programs/Xserver/randr/randrstr.h +++ b/nx-X11/programs/Xserver/randr/randrstr.h @@ -284,6 +284,19 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, typedef Bool (*RRCrtcSetScanoutPixmapProcPtr) (RRCrtcPtr crtc, PixmapPtr pixmap); +typedef Bool (*RRStartFlippingPixmapTrackingProcPtr)(RRCrtcPtr, PixmapPtr, + PixmapPtr, PixmapPtr, + int x, int y, + int dst_x, int dst_y, + Rotation rotation); + +typedef Bool (*RREnableSharedPixmapFlippingProcPtr)(RRCrtcPtr, + PixmapPtr front, + PixmapPtr back); + +typedef void (*RRDisableSharedPixmapFlippingProcPtr)(RRCrtcPtr); + + typedef struct _rrScrPriv { /* * 'public' part of the structure; DDXen fill this in @@ -310,6 +323,10 @@ typedef struct _rrScrPriv { /* TODO #if RANDR_15_INTERFACE */ RRCrtcSetScanoutPixmapProcPtr rrCrtcSetScanoutPixmap; + RRStartFlippingPixmapTrackingProcPtr rrStartFlippingPixmapTracking; + RREnableSharedPixmapFlippingProcPtr rrEnableSharedPixmapFlipping; + RRDisableSharedPixmapFlippingProcPtr rrDisableSharedPixmapFlipping; + RRProviderSetOutputSourceProcPtr rrProviderSetOutputSource; RRProviderSetOffloadSinkProcPtr rrProviderSetOffloadSink; RRProviderGetPropertyProcPtr rrProviderGetProperty; From ae21a94cc43e468bc3629ecc05b9beeaa66f1c19 Mon Sep 17 00:00:00 2001 From: Alex Goins Date: Fri, 10 Mar 2017 14:53:29 +0100 Subject: [PATCH 32/33] randr: Add ability to turn PRIME sync off Backport from X.org commit df8e86931eb19c196ed2afc85d89525ef8cb711b Author: agoins Date: Thu Jun 16 20:06:48 2016 -0700 randr: Add ability to turn PRIME sync off Adds an output parameter to disable PRIME synchronization. Output parameter is created when the user calls 'xrandr --setprovideroutputsource ' to prevent polluting output parameters of non-PRIME configurations. Defaults to on, so if the user wants PRIME synchronization they don't need to do anything. If the user wishes to disable PRIME synchronization when they first set up PRIME, they can run 'xrandr --output --set "PRIME Synchronization" 0' after running 'xrandr --setprovideroutputsource ', but before 'xrandr --auto'. If the user wishes to enable or disable PRIME synchronization after PRIME has already been set up, they can run 'xrandr --output --set "PRIME Synchronization" <0 or 1>' at any time, xrandr will trigger a modeset, which will tear down and setup PRIME in the configuration they requested on CRTCs associated with that output. randrstr.h: Add central definition of the output property name. rrcrtc.c: Add function rrGetPixmapSharingSyncProp() to query the status of the output property. Add function rrSetPixmapSharingSyncProp() to set the output property. Add 'sync' parameter to rrSetupPixmapSharing(), which when false will use single buffering even if the required ABI functions are supported. Changes rrSetupPixmapSharing() to only report an error if falling back to single buffering when the user requested synchronization. Change RRCrtcSet() to use rrPixmapSharingSyncProp() to query the status of the output property and feed it into rrSetupPixmapSharing() using the 'sync' parameter. rrprovider.c: Add RR(Init/Fini)PrimeSyncProps(), functions to create and destroy the PRIME synchronization output property. Add a call to RRInitPrimeSyncProps() in ProcRRSetProviderOutputSource(), such that the output property is created when the user requests PRIME. Add a call to RRFiniPrimeSyncProps() in RRProviderDestroy(). v1: Initial commit v2: Unchanged v3: Add /* TODO */ for handling different sources with different outputs Make rrSetupPixmapSharing() set the output property to 0 if it has to fall back, to avoid user confusion. Make rr(Get)PixmapSharingSyncProp() check the current value if there isn't a pending value v4: Unchanged v5: Unchanged v6: Rebase onto ToT v7: Unchanged Signed-off-by: Alex Goins Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/randrstr.h | 2 + nx-X11/programs/Xserver/randr/rrcrtc.c | 70 ++++++++++++++++++++-- nx-X11/programs/Xserver/randr/rrprovider.c | 57 ++++++++++++++++++ 3 files changed, 125 insertions(+), 4 deletions(-) diff --git a/nx-X11/programs/Xserver/randr/randrstr.h b/nx-X11/programs/Xserver/randr/randrstr.h index 63d5ffa55e..0dab942f3c 100644 --- a/nx-X11/programs/Xserver/randr/randrstr.h +++ b/nx-X11/programs/Xserver/randr/randrstr.h @@ -1036,6 +1036,8 @@ extern _X_EXPORT int ProcRRDeleteOutputProperty(ClientPtr client); /* rrprovider.c */ +#define PRIME_SYNC_PROP "PRIME Synchronization" + extern _X_EXPORT void RRProviderInitErrorValue(void); diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index 7d009b7ab0..5f186e1751 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -50,6 +50,8 @@ #include "swaprep.h" #include "mipointer.h" +#include + RESTYPE RRCrtcType; /* @@ -456,9 +458,60 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master, return spix; } +static Bool +rrGetPixmapSharingSyncProp(int numOutputs, RROutputPtr * outputs) +{ + /* Determine if the user wants prime syncing */ + int o; + const char *syncStr = PRIME_SYNC_PROP; + Atom syncProp = MakeAtom(syncStr, strlen(syncStr), FALSE); + if (syncProp == None) + return TRUE; + + /* If one output doesn't want sync, no sync */ + for (o = 0; o < numOutputs; o++) { + RRPropertyValuePtr val; + + /* Try pending value first, then current value */ + if ((val = RRGetOutputProperty(outputs[o], syncProp, TRUE)) && + val->data) { + if (!(*(char *) val->data)) + return FALSE; + continue; + } + + if ((val = RRGetOutputProperty(outputs[o], syncProp, FALSE)) && + val->data) { + if (!(*(char *) val->data)) + return FALSE; + continue; + } + } + + return TRUE; +} + +static void +rrSetPixmapSharingSyncProp(char val, int numOutputs, RROutputPtr * outputs) +{ + int o; + const char *syncStr = PRIME_SYNC_PROP; + Atom syncProp = MakeAtom(syncStr, strlen(syncStr), FALSE); + if (syncProp == None) + return; + + for (o = 0; o < numOutputs; o++) { + RRPropertyPtr prop = RRQueryOutputProperty(outputs[o], syncProp); + if (prop) + RRChangeOutputProperty(outputs[o], syncProp, XA_INTEGER, + 8, PropModeReplace, 1, &val, FALSE, TRUE); + } +} + static Bool rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, - int x, int y, Rotation rotation) + int x, int y, Rotation rotation, Bool sync, + int numOutputs, RROutputPtr * outputs) { ScreenPtr master = crtc->pScreen->current_master; rrScrPrivPtr pMasterScrPriv = rrGetScrPriv(master); @@ -505,7 +558,8 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, } /* Both source and sink must support required ABI funcs for flipping */ - if (pSlaveScrPriv->rrEnableSharedPixmapFlipping && + if (sync && + pSlaveScrPriv->rrEnableSharedPixmapFlipping && pSlaveScrPriv->rrDisableSharedPixmapFlipping && pMasterScrPriv->rrStartFlippingPixmapTracking && master->PresentSharedPixmap && @@ -545,7 +599,12 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, crtc->scanout_pixmap_back = NULL; } - ErrorF("randr: falling back to unsynchronized pixmap sharing\n"); + if (sync) { /* Wanted sync, didn't get it */ + ErrorF("randr: falling back to unsynchronized pixmap sharing\n"); + + /* Set output property to 0 to indicate to user */ + rrSetPixmapSharingSyncProp(0, numOutputs, outputs); + } if (!pSlaveScrPriv->rrCrtcSetScanoutPixmap(crtc, spix_front)) { rrDestroySharedPixmap(crtc, spix_front); @@ -724,7 +783,10 @@ RRCrtcSet(RRCrtcPtr crtc, return FALSE; if (pScreen->current_master) { - ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation); + Bool sync = rrGetPixmapSharingSyncProp(numOutputs, outputs); + ret = rrSetupPixmapSharing(crtc, width, height, + x, y, rotation, sync, + numOutputs, outputs); } } #if RANDR_12_INTERFACE diff --git a/nx-X11/programs/Xserver/randr/rrprovider.c b/nx-X11/programs/Xserver/randr/rrprovider.c index 01900ae450..bc6485adb5 100644 --- a/nx-X11/programs/Xserver/randr/rrprovider.c +++ b/nx-X11/programs/Xserver/randr/rrprovider.c @@ -25,6 +25,8 @@ #include "randrstr.h" #include "swaprep.h" +#include + RESTYPE RRProviderType; /* @@ -281,6 +283,58 @@ ProcRRGetProviderInfo(ClientPtr client) return Success; } +static void +RRInitPrimeSyncProps(ScreenPtr pScreen) +{ + /* + * TODO: When adding support for different sources for different outputs, + * make sure this sets up the output properties only on outputs associated + * with the correct source provider. + */ + + rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen); + + const char *syncStr = PRIME_SYNC_PROP; + Atom syncProp = MakeAtom(syncStr, strlen(syncStr), TRUE); + + int defaultVal = TRUE; + int validVals[2] = {FALSE, TRUE}; + + int i; + for (i = 0; i < pScrPriv->numOutputs; i++) { + if (!RRQueryOutputProperty(pScrPriv->outputs[i], syncProp)) { + RRConfigureOutputProperty(pScrPriv->outputs[i], syncProp, + TRUE, FALSE, FALSE, + 2, &validVals[0]); + RRChangeOutputProperty(pScrPriv->outputs[i], syncProp, XA_INTEGER, + 8, PropModeReplace, 1, &defaultVal, + FALSE, FALSE); + } + } +} + +static void +RRFiniPrimeSyncProps(ScreenPtr pScreen) +{ + /* + * TODO: When adding support for different sources for different outputs, + * make sure this tears down the output properties only on outputs + * associated with the correct source provider. + */ + + rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen); + int i; + + const char *syncStr = PRIME_SYNC_PROP; + Atom syncProp = MakeAtom(syncStr, strlen(syncStr), FALSE); + if (syncProp == None) + return; + + for (i = 0; i < pScrPriv->numOutputs; i++) { + RRDeleteOutputProperty(pScrPriv->outputs[i], syncProp); + } +} + int ProcRRSetProviderOutputSource(ClientPtr client) { @@ -313,6 +367,8 @@ ProcRRSetProviderOutputSource(ClientPtr client) pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider); + RRInitPrimeSyncProps(pScreen); + provider->changed = TRUE; RRSetChanged(pScreen); @@ -390,6 +446,7 @@ RRProviderCreate(ScreenPtr pScreen, const char *name, void RRProviderDestroy(RRProviderPtr provider) { + RRFiniPrimeSyncProps(provider->pScreen); FreeResource(provider->id, 0); } From 2bdba8e43ecd9cf0169f735423e147ddeca5b44e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 10 Mar 2017 14:57:15 +0100 Subject: [PATCH 33/33] randr: Add RRHasScanoutPixmap helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport from X.org: commit 2eefb53f58854ef9d34859583207ec37d3c3047a Author: Hans de Goede Date: Tue Sep 6 13:15:36 2016 +0200 randr: Add RRHasScanoutPixmap helper function This is a preparation patch for adding prime hw-cursor support. Signed-off-by: Hans de Goede Reviewed-by: Michel Dänzer Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/randr/randrstr.h | 6 ++++++ nx-X11/programs/Xserver/randr/rrcrtc.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/nx-X11/programs/Xserver/randr/randrstr.h b/nx-X11/programs/Xserver/randr/randrstr.h index 0dab942f3c..ad1258b962 100644 --- a/nx-X11/programs/Xserver/randr/randrstr.h +++ b/nx-X11/programs/Xserver/randr/randrstr.h @@ -822,6 +822,12 @@ extern _X_EXPORT void extern _X_EXPORT Bool RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable); +/* + * Return if the screen has any scanout_pixmap's attached + */ +extern _X_EXPORT Bool + RRHasScanoutPixmap(ScreenPtr pScreen); + /* * Crtc dispatch */ diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index 5f186e1751..7ea46ebbdd 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -2031,3 +2031,23 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable) return ret; } + + +Bool +RRHasScanoutPixmap(ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + int i; + + if (!pScreen->is_output_slave) + return FALSE; + + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + + if (crtc->scanout_pixmap) + return TRUE; + } + + return FALSE; +}