From b8a3be5f34016b745e38cd53825a4e398c6127bc Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 24 Feb 2010 23:17:59 +0100 Subject: [PATCH 1/3] Add a ConfigNotify hook. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Executed from the ConfigureWindow request, right before sending ConfigureNotify to the clients. This commit breaks the ScreenRec ABI. Signed-off-by: Francisco Jerez Signed-off-by: Kristian Høgsberg Reviewed-by: Kristian Høgsberg --- dix/window.c | 3 +++ include/scrnintstr.h | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/dix/window.c b/dix/window.c index 2676a546a..c7201df09 100644 --- a/dix/window.c +++ b/dix/window.c @@ -2303,6 +2303,9 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) return(Success); ActuallyDoSomething: + if (pWin->drawable.pScreen->ConfigNotify) + (*pWin->drawable.pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib); + if (SubStrSend(pWin, pParent)) { memset(&event, 0, sizeof(xEvent)); diff --git a/include/scrnintstr.h b/include/scrnintstr.h index ab50e7a32..c42119d0d 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -399,6 +399,15 @@ typedef void (* PostChangeSaveUnderProcPtr)( WindowPtr /*pLayerWin*/, WindowPtr /*firstChild*/); +typedef void (* ConfigNotifyProcPtr)( + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + int /*bw*/, + WindowPtr /*pSib*/); + typedef void (* MoveWindowProcPtr)( WindowPtr /*pWin*/, int /*x*/, @@ -581,6 +590,7 @@ typedef struct _Screen { MarkOverlappedWindowsProcPtr MarkOverlappedWindows; ChangeSaveUnderProcPtr ChangeSaveUnder; PostChangeSaveUnderProcPtr PostChangeSaveUnder; + ConfigNotifyProcPtr ConfigNotify; MoveWindowProcPtr MoveWindow; ResizeWindowProcPtr ResizeWindow; GetLayerWindowProcPtr GetLayerWindow; From e38e01081af42825bb7b44d18aa35845318f8556 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 24 Feb 2010 23:18:00 +0100 Subject: [PATCH 2/3] Import linked list helpers from the intel DDX. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Borrowed from i830.h, except for list_for_each_entry(). Signed-off-by: Francisco Jerez Signed-off-by: Kristian Høgsberg Reviewed-by: Kristian Høgsberg --- include/Makefile.am | 1 + include/list.h | 97 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 include/list.h diff --git a/include/Makefile.am b/include/Makefile.am index d684f9c2b..eddc86cb3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -27,6 +27,7 @@ sdk_HEADERS = \ globals.h \ input.h \ inputstr.h \ + list.h \ misc.h \ miscstruct.h \ opaque.h \ diff --git a/include/list.h b/include/list.h new file mode 100644 index 000000000..a126a652d --- /dev/null +++ b/include/list.h @@ -0,0 +1,97 @@ +/* + * 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 _LIST_H_ +#define _LIST_H_ + +/* classic doubly-link circular list */ +struct list { + struct list *next, *prev; +}; + +static void +list_init(struct list *list) +{ + list->next = list->prev = list; +} + +static inline void +__list_add(struct list *entry, + struct list *prev, + struct list *next) +{ + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; +} + +static inline void +list_add(struct list *entry, struct list *head) +{ + __list_add(entry, head, head->next); +} + +static inline void +__list_del(struct list *prev, struct list *next) +{ + next->prev = prev; + prev->next = next; +} + +static inline void +list_del(struct list *entry) +{ + __list_del(entry->prev, entry->next); + list_init(entry); +} + +static inline Bool +list_is_empty(struct list *head) +{ + return head->next == head; +} + +#ifndef container_of +#define container_of(ptr, type, member) \ + (type *)((char *)(ptr) - (char *) &((type *)0)->member) +#endif + +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +#define __container_of(ptr, sample, member) \ + (void *)((char *)(ptr) \ + - ((char *)&(sample)->member - (char *)(sample))) + +#define list_for_each_entry(pos, head, member) \ + for (pos = __container_of((head)->next, pos, member); \ + &pos->member != (head); \ + pos = __container_of(pos->member.next, pos, member)) + +#endif From fa5103a02bd509e4a102afdad2ab26cb22210367 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 24 Feb 2010 23:18:01 +0100 Subject: [PATCH 3/3] dri2: No need to blit from front on DRI2GetBuffers if they're just being reused. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can be quite an expensive operation, so we're better off not doing it unless it's totally required. Signed-off-by: Francisco Jerez Signed-off-by: Kristian Høgsberg Reviewed-by: Kristian Høgsberg --- hw/xfree86/dri2/dri2.c | 46 +++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index cd69ca0c4..48618e1a5 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -202,27 +202,25 @@ find_attachment(DRI2DrawablePtr pPriv, unsigned attachment) return -1; } -static DRI2BufferPtr +static Bool allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds, DRI2DrawablePtr pPriv, unsigned int attachment, unsigned int format, - int dimensions_match) + int dimensions_match, DRI2BufferPtr *buffer) { - DRI2BufferPtr buffer; - int old_buf; - - old_buf = find_attachment(pPriv, attachment); + int old_buf = find_attachment(pPriv, attachment); if ((old_buf < 0) || !dimensions_match || (pPriv->buffers[old_buf]->format != format)) { - buffer = (*ds->CreateBuffer)(pDraw, attachment, format); - } else { - buffer = pPriv->buffers[old_buf]; - pPriv->buffers[old_buf] = NULL; - } + *buffer = (*ds->CreateBuffer)(pDraw, attachment, format); + return TRUE; - return buffer; + } else { + *buffer = pPriv->buffers[old_buf]; + pPriv->buffers[old_buf] = NULL; + return FALSE; + } } static DRI2BufferPtr * @@ -238,6 +236,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, int have_fake_front = 0; int front_format = 0; int dimensions_match; + int buffers_changed = 0; int i; if (!pPriv) { @@ -256,8 +255,10 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, const unsigned attachment = *(attachments++); const unsigned format = (has_format) ? *(attachments++) : 0; - buffers[i] = allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment, - format, dimensions_match); + if (allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment, + format, dimensions_match, + &buffers[i])) + buffers_changed = 1; /* If the drawable is a window and the front-buffer is requested, * silently add the fake front-buffer to the list of requested @@ -287,15 +288,18 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, } if (need_real_front > 0) { - buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv, - DRI2BufferFrontLeft, - front_format, dimensions_match); + if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFrontLeft, + front_format, dimensions_match, + &buffers[i++])) + buffers_changed = 1; } if (need_fake_front > 0) { - buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv, - DRI2BufferFakeFrontLeft, - front_format, dimensions_match); + if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFakeFrontLeft, + front_format, dimensions_match, + &buffers[i++])) + buffers_changed = 1; + have_fake_front = 1; } @@ -324,7 +328,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, * contents of the real front-buffer. This ensures correct operation of * applications that call glXWaitX before calling glDrawBuffer. */ - if (have_fake_front) { + if (have_fake_front && buffers_changed) { BoxRec box; RegionRec region;