From 1ad9f01c31742157934a791e6141d10520d13e8a Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 10 Mar 2011 10:47:40 -0500 Subject: [PATCH 01/16] glx: Add texbuffer2 support to swrast Reviewed-by: Julien Cristau Signed-off-by: Adam Jackson --- glx/glxdriswrast.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c index 08ea33865..f88d04f55 100644 --- a/glx/glxdriswrast.c +++ b/glx/glxdriswrast.c @@ -201,6 +201,14 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, if (texBuffer == NULL) return Success; +#if __DRI_TEX_BUFFER_VERSION >= 2 + if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) { + (*texBuffer->setTexBuffer2)(context->driContext, + glxPixmap->target, + glxPixmap->format, + drawable->driDrawable); + } else +#endif texBuffer->setTexBuffer(context->driContext, glxPixmap->target, drawable->driDrawable); From 92788e677be79bd04e5ef140f4ced50ad8b1bf8e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 22 Feb 2011 12:32:01 +1000 Subject: [PATCH 02/16] test: add some tests for basic list manipulation. This has less purpose as a test but more as documentation on how to actually use the differnent list calls. Reviewed-by: Adam Jackson Signed-off-by: Peter Hutterer --- test/Makefile.am | 3 +- test/list.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 test/list.c diff --git a/test/Makefile.am b/test/Makefile.am index 456221e46..be54e5f24 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,6 @@ if UNITTESTS SUBDIRS= . xi2 -check_PROGRAMS = xkb input xtest +check_PROGRAMS = xkb input xtest list check_LTLIBRARIES = libxservertest.la TESTS=$(check_PROGRAMS) @@ -16,6 +16,7 @@ endif xkb_LDADD=$(TEST_LDADD) input_LDADD=$(TEST_LDADD) xtest_LDADD=$(TEST_LDADD) +list_LDADD=$(TEST_LDADD) libxservertest_la_LIBADD = \ $(XSERVER_LIBS) \ diff --git a/test/list.c b/test/list.c new file mode 100644 index 000000000..a87d2db70 --- /dev/null +++ b/test/list.c @@ -0,0 +1,176 @@ +/** + * Copyright © 2011 Red Hat, Inc. + * + * 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +struct parent { + int a; + struct list children; + int b; +}; + +struct child { + int foo; + int bar; + struct list node; +}; + +static void +test_list_init(void) +{ + struct parent parent, tmp; + + memset(&parent, 0, sizeof(parent)); + parent.a = 0xa5a5a5; + parent.b = ~0xa5a5a5; + + tmp = parent; + + list_init(&parent.children); + + /* test we haven't touched anything else. */ + g_assert(parent.a == tmp.a); + g_assert(parent.b == tmp.b); + + g_assert(list_is_empty(&parent.children)); +} + +static void +test_list_add(void) +{ + struct parent parent = {0}; + struct child child[3]; + struct child *c; + + list_init(&parent.children); + + list_add(&child[0].node, &parent.children); + g_assert(!list_is_empty(&parent.children)); + + c = list_first_entry(&parent.children, struct child, node); + g_assert(memcmp(c, &child[0], sizeof(struct child)) == 0); + + /* note: list_add prepends */ + list_add(&child[1].node, &parent.children); + c = list_first_entry(&parent.children, struct child, node); + g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0); + + list_add(&child[2].node, &parent.children); + c = list_first_entry(&parent.children, struct child, node); + g_assert(memcmp(c, &child[2], sizeof(struct child)) == 0); +}; + +static void +test_list_del(void) +{ + struct parent parent = {0}; + struct child child[3]; + struct child *c; + + list_init(&parent.children); + + list_add(&child[0].node, &parent.children); + g_assert(!list_is_empty(&parent.children)); + + list_del(&parent.children); + g_assert(list_is_empty(&parent.children)); + + list_add(&child[0].node, &parent.children); + list_del(&child[0].node); + g_assert(list_is_empty(&parent.children)); + + list_add(&child[0].node, &parent.children); + list_add(&child[1].node, &parent.children); + + c = list_first_entry(&parent.children, struct child, node); + g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0); + + /* delete first node */ + list_del(&child[1].node); + g_assert(!list_is_empty(&parent.children)); + g_assert(list_is_empty(&child[1].node)); + c = list_first_entry(&parent.children, struct child, node); + g_assert(memcmp(c, &child[0], sizeof(struct child)) == 0); + + /* delete last node */ + list_add(&child[1].node, &parent.children); + list_del(&child[0].node); + c = list_first_entry(&parent.children, struct child, node); + g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0); + + /* delete list head */ + list_add(&child[0].node, &parent.children); + list_del(&parent.children); + g_assert(list_is_empty(&parent.children)); + g_assert(!list_is_empty(&child[1].node)); + g_assert(!list_is_empty(&child[2].node)); +} + +static void +test_list_for_each(void) +{ + struct parent parent = {0}; + struct child child[3]; + struct child *c; + int i = 0; + + list_init(&parent.children); + + list_add(&child[2].node, &parent.children); + list_add(&child[1].node, &parent.children); + list_add(&child[0].node, &parent.children); + + list_for_each_entry(c, &parent.children, node) { + g_assert(memcmp(c, &child[i], sizeof(struct child)) == 0); + i++; + } + + /* foreach on empty list */ + list_del(&parent.children); + g_assert(list_is_empty(&parent.children)); + + list_for_each_entry(c, &parent.children, node) { + g_assert(0); /* we must not get here */ + } +} + + +int main(int argc, char** argv) +{ + g_test_init(&argc, &argv,NULL); + g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id="); + + g_test_add_func("/list/init", test_list_init); + g_test_add_func("/list/add", test_list_add); + g_test_add_func("/list/del", test_list_del); + g_test_add_func("/list/for_each", test_list_for_each); + + return g_test_run(); +} From 769531b9ccade723a56498b0888af58d085fec9e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 14:19:18 +1000 Subject: [PATCH 03/16] Add mode field to pointer movement hooks. Preparation work for pointer barriers. Reviewed-by: Adam Jackson Signed-off-by: Peter Hutterer --- dix/getevents.c | 12 +++++++++--- mi/mipointer.c | 6 +++++- mi/mipointer.h | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index 5b8e3798d..cba616311 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -812,7 +812,11 @@ accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms) * miPointerSetPosition() and then scale back into device coordinates (if * needed). miPSP will change x/y if the screen was crossed. * + * The coordinates provided are always absolute. The parameter mode whether + * it was relative or absolute movement that landed us at those coordinates. + * * @param dev The device to be moved. + * @param mode Movement mode (Absolute or Relative) * @param x Pointer to current x-axis value, may be modified. * @param y Pointer to current y-axis value, may be modified. * @param x_frac Fractional part of current x-axis value, may be modified. @@ -824,7 +828,8 @@ accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms) * @param screeny_frac Fractional part of screen y coordinate, as above. */ static void -positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac, +positionSprite(DeviceIntPtr dev, int mode, + int *x, int *y, float x_frac, float y_frac, ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac) { int old_screenx, old_screeny; @@ -863,7 +868,7 @@ positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac, old_screeny = *screeny; /* This takes care of crossing screens for us, as well as clipping * to the current screen. */ - miPointerSetPosition(dev, screenx, screeny); + miPointerSetPosition(dev, mode, screenx, screeny); if(!IsMaster(dev) || !IsFloating(dev)) { DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); @@ -1194,7 +1199,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, set_raw_valuators(raw, &mask, raw->valuators.data); - positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac); + positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, + &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac); updateHistory(pDev, &mask, ms); /* Update the valuators with the true value sent to the client*/ diff --git a/mi/mipointer.c b/mi/mipointer.c index 209ea06be..520583f46 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -560,14 +560,18 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, * This function is called during the pointer update path in * GetPointerEvents and friends (and the same in the xwin DDX). * + * The coordinates provided are always absolute. The parameter mode whether + * it was relative or absolute movement that landed us at those coordinates. + * * @param pDev The device to move + * @param mode Movement mode (Absolute or Relative) * @param[in,out] x The x coordiante in screen coordinates (in regards to total * desktop size) * @param[in,out] y The y coordiante in screen coordinates (in regards to total * desktop size) */ void -miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y) +miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; diff --git a/mi/mipointer.h b/mi/mipointer.h index 3c8611022..539096e78 100644 --- a/mi/mipointer.h +++ b/mi/mipointer.h @@ -133,6 +133,7 @@ extern _X_EXPORT void miPointerGetPosition( * x and y are modified in-place. */ extern _X_EXPORT void miPointerSetPosition( DeviceIntPtr pDev, + int mode, int *x, int *y); From 810fbfa44626bff9f443ab17c0ad27ff7ae121d7 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 9 Feb 2011 17:32:16 -0500 Subject: [PATCH 04/16] mi: Call pScreen->ConstrainCursorHarder from the position update path v2: Cover more paths, spotted by Daniel Stone. v3: pass down the mode field for movement mode. Reviewed-by: Daniel Stone Signed-off-by: Adam Jackson Signed-off-by: Peter Hutterer --- mi/mipointer.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mi/mipointer.c b/mi/mipointer.c index 520583f46..c578d0b1d 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -272,6 +272,9 @@ miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, pPointer->generateEvent = generateEvent; + if (pScreen->ConstrainCursorHarder) + pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y); + /* device dependent - must pend signal and call miPointerWarpCursor */ (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); if (!generateEvent) @@ -616,6 +619,9 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) if (*y >= pPointer->limits.y2) *y = pPointer->limits.y2 - 1; + if (pScreen->ConstrainCursorHarder) + pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y); + if (pPointer->x == *x && pPointer->y == *y && pPointer->pScreen == pScreen) return; From 56c90e29f04727c903bd0f084d23bf44eb1a0a11 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 15 Nov 2010 14:29:14 -0500 Subject: [PATCH 05/16] randr: Add RRConstrainCursorHarder Confine cursor motion to within the bounds of a single CRTC, iff all the CRTCs within a ScreenRec are reachable from each other. If not you get the same "cursor floats within the bounding rect" behaviour you get now. v3: - Incorporate review feedback from Christopher James Halse Rogers v4: - Add mode field. Signed-off-by: Adam Jackson Signed-off-by: Peter Hutterer --- randr/randr.c | 2 + randr/randrstr.h | 4 ++ randr/rrcrtc.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) diff --git a/randr/randr.c b/randr/randr.c index 607770520..d33712928 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -270,6 +270,8 @@ Bool RRScreenInit(ScreenPtr pScreen) wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); + pScreen->ConstrainCursorHarder = RRConstrainCursorHarder; + pScrPriv->numOutputs = 0; pScrPriv->outputs = NULL; pScrPriv->numCrtcs = 0; diff --git a/randr/randrstr.h b/randr/randrstr.h index 7ea608003..d8dd37d96 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -297,6 +297,7 @@ typedef struct _rrScrPriv { int rate; int size; #endif + Bool discontiguous; } rrScrPrivRec, *rrScrPrivPtr; extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec; @@ -700,6 +701,9 @@ ProcRRGetPanning (ClientPtr client); int ProcRRSetPanning (ClientPtr client); +void +RRConstrainCursorHarder (DeviceIntPtr, ScreenPtr, int, int *, int *); + /* rrdispatch.c */ extern _X_EXPORT Bool RRClientKnowsRates (ClientPtr pClient); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 98206a2b9..d4d8f2ad2 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -1,5 +1,6 @@ /* * Copyright © 2006 Keith Packard + * Copyright 2010 Red Hat, Inc * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -22,6 +23,7 @@ #include "randrstr.h" #include "swaprep.h" +#include "mipointer.h" RESTYPE RRCrtcType; @@ -292,6 +294,92 @@ RRCrtcPendingProperties (RRCrtcPtr crtc) return FALSE; } +static void +crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom) +{ + *left = crtc->x; + *top = crtc->y; + + switch (crtc->rotation) { + case RR_Rotate_0: + case RR_Rotate_180: + default: + *right = crtc->x + crtc->mode->mode.width; + *bottom = crtc->y + crtc->mode->mode.height; + return; + case RR_Rotate_90: + case RR_Rotate_270: + *right = crtc->x + crtc->mode->mode.height; + *bottom = crtc->y + crtc->mode->mode.width; + return; + } +} + +/* overlapping counts as adjacent */ +static Bool +crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b) +{ + /* left, right, top, bottom... */ + int al, ar, at, ab; + int bl, br, bt, bb; + int cl, cr, ct, cb; /* the overlap, if any */ + + crtc_bounds(a, &al, &ar, &at, &ab); + crtc_bounds(b, &bl, &br, &bt, &bb); + + cl = max(al, bl); + cr = min(ar, br); + ct = max(at, bt); + cb = min(ab, bb); + + return (cl <= cr) && (ct <= cb); +} + +/* Depth-first search and mark all CRTCs reachable from cur */ +static void +mark_crtcs (rrScrPrivPtr pScrPriv, int *reachable, int cur) +{ + int i; + reachable[cur] = TRUE; + for (i = 0; i < pScrPriv->numCrtcs; ++i) { + if (reachable[i] || !pScrPriv->crtcs[i]->mode) + continue; + if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i])) + mark_crtcs(pScrPriv, reachable, i); + } +} + +static void +RRComputeContiguity (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + Bool discontiguous = TRUE; + int i, n = pScrPriv->numCrtcs; + + int *reachable = calloc(n, sizeof(int)); + if (!reachable) + goto out; + + /* Find first enabled CRTC and start search for reachable CRTCs from it */ + for (i = 0; i < n; ++i) { + if (pScrPriv->crtcs[i]->mode) { + mark_crtcs(pScrPriv, reachable, i); + break; + } + } + + /* Check that all enabled CRTCs were marked as reachable */ + for (i = 0; i < n; ++i) + if (pScrPriv->crtcs[i]->mode && !reachable[i]) + goto out; + + discontiguous = FALSE; + +out: + free(reachable); + pScrPriv->discontiguous = discontiguous; +} + /* * Request that the Crtc be reconfigured */ @@ -306,6 +394,7 @@ RRCrtcSet (RRCrtcPtr crtc, { ScreenPtr pScreen = crtc->pScreen; Bool ret = FALSE; + Bool recompute = TRUE; rrScrPriv(pScreen); /* See if nothing changed */ @@ -318,6 +407,7 @@ RRCrtcSet (RRCrtcPtr crtc, !RRCrtcPendingProperties (crtc) && !RRCrtcPendingTransform (crtc)) { + recompute = FALSE; ret = TRUE; } else @@ -381,6 +471,10 @@ RRCrtcSet (RRCrtcPtr crtc, RRPostPendingProperties (outputs[o]); } } + + if (recompute) + RRComputeContiguity(pScreen); + return ret; } @@ -1349,3 +1443,64 @@ ProcRRGetCrtcTransform (ClientPtr client) free(reply); return Success; } + +void +RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, int *y) +{ + rrScrPriv (pScreen); + int i; + + /* intentional dead space -> let it float */ + if (pScrPriv->discontiguous) + return; + + /* if we're moving inside a crtc, we're fine */ + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + + int left, right, top, bottom; + + if (!crtc->mode) + continue; + + crtc_bounds(crtc, &left, &right, &top, &bottom); + + if ((*x >= left) && (*x <= right) && (*y >= top) && (*y <= bottom)) + return; + } + + /* if we're trying to escape, clamp to the CRTC we're coming from */ + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + int nx, ny; + int left, right, top, bottom; + + if (!crtc->mode) + continue; + + crtc_bounds(crtc, &left, &right, &top, &bottom); + miPointerGetPosition(pDev, &nx, &ny); + + if ((nx >= left) && (nx <= right) && (ny >= top) && (ny <= bottom)) { + if ((*x <= left) || (*x >= right)) { + int dx = *x - nx; + + if (dx > 0) + *x = right; + else if (dx < 0) + *x = left; + } + + if ((*y <= top) || (*y >= bottom)) { + int dy = *y - ny; + + if (dy > 0) + *y = bottom; + else if (dy < 0) + *y = top; + } + + return; + } + } +} From 021393d1b8bcc9ff2ff5deb2306360e6b0afa1c6 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Wed, 9 Mar 2011 11:15:07 +1100 Subject: [PATCH 06/16] glx: Factor out glxProbeDriver function. DRI, DRI2 and swrast all had near-identical driver probing logic. Pull it into glxdricommon. [ajax: warning fix] Reviewed-by: Adam Jackson Signed-off-by: Christopher James Halse Rogers --- glx/glxdri.c | 44 +++++------------------------------ glx/glxdri2.c | 39 +++---------------------------- glx/glxdricommon.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ glx/glxdricommon.h | 5 ++++ glx/glxdriswrast.c | 42 +++++----------------------------- 5 files changed, 77 insertions(+), 110 deletions(-) diff --git a/glx/glxdri.c b/glx/glxdri.c index 7717fcfb7..3a573372a 100644 --- a/glx/glxdri.c +++ b/glx/glxdri.c @@ -858,8 +858,6 @@ static const __DRIextension *loader_extensions[] = { -static const char dri_driver_path[] = DRI_DRIVER_PATH; - static Bool glxDRIEnterVT (int index, int flags) { @@ -971,13 +969,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen) drm_handle_t hFB; int junk; __GLXDRIscreen *screen; - char filename[128]; Bool isCapable; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; const __DRIconfig **driConfigs; - const __DRIextension **extensions; - int i; if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") || !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || @@ -1052,42 +1047,15 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - snprintf(filename, sizeof filename, "%s/%s_dri.so", - dri_driver_path, driverName); - - screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + screen->driver = glxProbeDriver(driverName, + (void **)&screen->core, + __DRI_CORE, __DRI_CORE_VERSION, + (void **)&screen->legacy, + __DRI_LEGACY, __DRI_LEGACY_VERSION); if (screen->driver == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", - filename, dlerror()); goto handle_error; } - - extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", - driverName, dlerror()); - goto handle_error; - } - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && - extensions[i]->version >= __DRI_CORE_VERSION) { - screen->core = (__DRIcoreExtension *) extensions[i]; - } - - if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 && - extensions[i]->version >= __DRI_LEGACY_VERSION) { - screen->legacy = (__DRIlegacyExtension *) extensions[i]; - } - } - - if (screen->core == NULL || screen->legacy == NULL) { - LogMessage(X_ERROR, - "AIGLX error: %s does not export required DRI extension\n", - driverName); - goto handle_error; - } - /* * Get device-specific info. pDevPriv will point to a struct * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that @@ -1172,7 +1140,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) pScrn->LeaveVT = glxDRILeaveVT; LogMessage(X_INFO, - "AIGLX: Loaded and initialized %s\n", filename); + "AIGLX: Loaded and initialized %s\n", driverName); return &screen->base; diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 8d21c937b..18927d75d 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -599,8 +599,6 @@ static const __DRIextension *loader_extensions[] = { NULL }; -static const char dri_driver_path[] = DRI_DRIVER_PATH; - static Bool glxDRIEnterVT (int index, int flags) { @@ -702,12 +700,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen) { const char *driverName, *deviceName; __GLXDRIscreen *screen; - char filename[128]; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - const __DRIextension **extensions; const __DRIconfig **driConfigs; - int i; screen = calloc(1, sizeof *screen); if (screen == NULL) @@ -729,40 +724,12 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __glXInitExtensionEnableBits(screen->glx_enable_bits); - snprintf(filename, sizeof filename, - "%s/%s_dri.so", dri_driver_path, driverName); - - screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + screen->driver = glxProbeDriver(driverName, (void **)&screen->core, __DRI_CORE, 1, + (void **)&screen->dri2, __DRI_DRI2, 1); if (screen->driver == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", - filename, dlerror()); goto handle_error; } - - extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", - driverName, dlerror()); - goto handle_error; - } - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && - extensions[i]->version >= 1) { - screen->core = (const __DRIcoreExtension *) extensions[i]; - } - if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 && - extensions[i]->version >= 1) { - screen->dri2 = (const __DRIdri2Extension *) extensions[i]; - } - } - - if (screen->core == NULL || screen->dri2 == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n", - driverName); - goto handle_error; - } - screen->driScreen = (*screen->dri2->createNewScreen)(pScreen->myNum, screen->fd, @@ -816,7 +783,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) pScrn->LeaveVT = glxDRILeaveVT; LogMessage(X_INFO, - "AIGLX: Loaded and initialized %s\n", filename); + "AIGLX: Loaded and initialized %s\n", driverName); return &screen->base; diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c index 86797a0ef..daa955db8 100644 --- a/glx/glxdricommon.c +++ b/glx/glxdricommon.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -204,3 +205,59 @@ glxConvertConfigs(const __DRIcoreExtension *core, return head.next; } + +static const char dri_driver_path[] = DRI_DRIVER_PATH; + +void * +glxProbeDriver(const char *driverName, + void **coreExt, const char *coreName, int coreVersion, + void **renderExt, const char *renderName, int renderVersion) +{ + int i; + void *driver; + char filename[128]; + const __DRIextension **extensions; + + snprintf(filename, sizeof filename, "%s/%s_dri.so", + dri_driver_path, driverName); + + driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + if (driver == NULL) { + LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", + filename, dlerror()); + goto cleanup_failure; + } + + extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", + driverName, dlerror()); + goto cleanup_failure; + } + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, coreName) == 0 && + extensions[i]->version >= coreVersion) { + *coreExt = (void *)extensions[i]; + } + + if (strcmp(extensions[i]->name, renderName) == 0 && + extensions[i]->version >= renderVersion) { + *renderExt = (void *)extensions[i]; + } + } + + if (*coreExt == NULL || *renderExt == NULL) { + LogMessage(X_ERROR, + "AIGLX error: %s does not export required DRI extension\n", + driverName); + goto cleanup_failure; + } + return driver; + +cleanup_failure: + if (driver) + dlclose(driver); + *coreExt = *renderExt = NULL; + return NULL; +} diff --git a/glx/glxdricommon.h b/glx/glxdricommon.h index 41e2d2770..2c55e60a6 100644 --- a/glx/glxdricommon.h +++ b/glx/glxdricommon.h @@ -38,4 +38,9 @@ glxConvertConfigs(const __DRIcoreExtension *core, extern const __DRIsystemTimeExtension systemTimeExtension; +void * +glxProbeDriver(const char *name, + void **coreExt, const char *coreName, int coreVersion, + void **renderExt, const char *renderName, int renderVersion); + #endif diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c index f88d04f55..78b24ff62 100644 --- a/glx/glxdriswrast.c +++ b/glx/glxdriswrast.c @@ -435,17 +435,12 @@ initializeExtensions(__GLXDRIscreen *screen) } } -static const char dri_driver_path[] = DRI_DRIVER_PATH; - static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { const char *driverName = "swrast"; __GLXDRIscreen *screen; - char filename[128]; - const __DRIextension **extensions; const __DRIconfig **driConfigs; - int i; screen = calloc(1, sizeof *screen); if (screen == NULL) @@ -457,40 +452,15 @@ __glXDRIscreenProbe(ScreenPtr pScreen) screen->base.swapInterval = NULL; screen->base.pScreen = pScreen; - snprintf(filename, sizeof filename, - "%s/%s_dri.so", dri_driver_path, driverName); - - screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + screen->driver = glxProbeDriver(driverName, + (void **)&screen->core, + __DRI_CORE, __DRI_CORE_VERSION, + (void **)&screen->swrast, + __DRI_SWRAST, __DRI_SWRAST_VERSION); if (screen->driver == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", - filename, dlerror()); goto handle_error; } - extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", - driverName, dlerror()); - goto handle_error; - } - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && - extensions[i]->version >= __DRI_CORE_VERSION) { - screen->core = (const __DRIcoreExtension *) extensions[i]; - } - if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0 && - extensions[i]->version >= __DRI_SWRAST_VERSION) { - screen->swrast = (const __DRIswrastExtension *) extensions[i]; - } - } - - if (screen->core == NULL || screen->swrast == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n", - driverName); - goto handle_error; - } - screen->driScreen = (*screen->swrast->createNewScreen)(pScreen->myNum, loader_extensions, @@ -516,7 +486,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) screen->base.GLXminor = 4; LogMessage(X_INFO, - "AIGLX: Loaded and initialized %s\n", filename); + "AIGLX: Loaded and initialized %s\n", driverName); return &screen->base; From d17a9fb8414becf6a8998041df68f209f9222b2b Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Wed, 9 Mar 2011 11:17:27 +1100 Subject: [PATCH 07/16] Consolidate all the PATH_MAX handling into misc.h Reviewed-by: Adam Jackson Signed-off-by: Christopher James Halse Rogers --- hw/xfree86/common/xf86Configure.c | 5 +---- hw/xfree86/os-support/xf86_OSlib.h | 11 +++-------- hw/xfree86/parser/scan.c | 11 +++-------- include/misc.h | 11 +++++++++++ os/access.c | 19 ------------------- os/osinit.c | 9 +-------- os/utils.c | 11 ----------- 7 files changed, 19 insertions(+), 58 deletions(-) diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c index 883c48cc0..c712df72c 100644 --- a/hw/xfree86/common/xf86Configure.c +++ b/hw/xfree86/common/xf86Configure.c @@ -39,6 +39,7 @@ #include "xf86Bus.h" #include "xf86Sbus.h" #endif +#include "misc.h" typedef struct _DevToConfig { GDevRec GDev; @@ -514,10 +515,6 @@ configureDDCMonitorSection (int screennum) return ptr; } -#if !defined(PATH_MAX) -# define PATH_MAX 1024 -#endif - void DoConfigure(void) { diff --git a/hw/xfree86/os-support/xf86_OSlib.h b/hw/xfree86/os-support/xf86_OSlib.h index 147a201ee..24c92fbbc 100644 --- a/hw/xfree86/os-support/xf86_OSlib.h +++ b/hw/xfree86/os-support/xf86_OSlib.h @@ -370,6 +370,9 @@ #include /* May need to adjust this for other OSs */ +/* For PATH_MAX */ +#include "misc.h" + /* * Hack originally for ISC 2.2 POSIX headers, but may apply elsewhere, * and it's safe, so just do it. @@ -390,14 +393,6 @@ # undef _POSIX_SOURCE #endif /* _POSIX_SOURCE */ -#if !defined(PATH_MAX) -# if defined(MAXPATHLEN) -# define PATH_MAX MAXPATHLEN -# else -# define PATH_MAX 1024 -# endif /* MAXPATHLEN */ -#endif /* !PATH_MAX */ - #ifndef DEV_MEM #define DEV_MEM "/dev/mem" diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c index e4fce309f..1cff3bc5c 100644 --- a/hw/xfree86/parser/scan.c +++ b/hw/xfree86/parser/scan.c @@ -77,18 +77,13 @@ #undef _POSIX_SOURCE #endif /* _POSIX_SOURCE */ -#if !defined(PATH_MAX) -#if defined(MAXPATHLEN) -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif /* MAXPATHLEN */ -#endif /* !PATH_MAX */ - #if !defined(MAXHOSTNAMELEN) #define MAXHOSTNAMELEN 32 #endif /* !MAXHOSTNAMELEN */ +/* For PATH_MAX */ +#include "misc.h" + #include "Configint.h" #include "xf86tokens.h" diff --git a/include/misc.h b/include/misc.h index 0717db64d..b0abf9ac9 100644 --- a/include/misc.h +++ b/include/misc.h @@ -178,6 +178,17 @@ typedef struct _xReq *xReqPtr; #endif +#ifndef PATH_MAX +#include +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + /** * Calculate the number of bytes needed to hold bits. * @param bits The minimum number of bits needed. diff --git a/os/access.c b/os/access.c index eb1a21d42..3856e606e 100644 --- a/os/access.c +++ b/os/access.c @@ -165,17 +165,6 @@ SOFTWARE. #endif /* WIN32 */ -#ifndef PATH_MAX -#include -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif -#endif - #define X_INCLUDE_NETDB_H #include @@ -185,14 +174,6 @@ SOFTWARE. #include "xace.h" -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif - Bool defeatAccessControl = FALSE; #define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len) diff --git a/os/osinit.c b/os/osinit.c index 018e4047d..45d202def 100644 --- a/os/osinit.c +++ b/os/osinit.c @@ -63,17 +63,10 @@ SOFTWARE. #include #endif +#include "misc.h" #include "dixstruct.h" -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif - #if !defined(SYSV) && !defined(WIN32) #include diff --git a/os/utils.c b/os/utils.c index 18fd91151..a365aca81 100644 --- a/os/utils.c +++ b/os/utils.c @@ -231,17 +231,6 @@ OsSignal(int sig, OsSigHandlerPtr handler) #define LOCK_PREFIX "/.X" #define LOCK_SUFFIX "-lock" -#ifndef PATH_MAX -#include -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif -#endif - static Bool StillLocking = FALSE; static char LockFile[PATH_MAX]; static Bool nolock = FALSE; From 7ca75abbbdd2a1211e52a4f43ac4ed24d3c8ab34 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Wed, 9 Mar 2011 11:17:28 +1100 Subject: [PATCH 08/16] glx: Use PATH_MAX as size of filename buffer Reviewed-by: Adam Jackson Signed-off-by: Christopher James Halse Rogers --- glx/glxdricommon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c index daa955db8..9149e0db1 100644 --- a/glx/glxdricommon.c +++ b/glx/glxdricommon.c @@ -215,7 +215,7 @@ glxProbeDriver(const char *driverName, { int i; void *driver; - char filename[128]; + char filename[PATH_MAX]; const __DRIextension **extensions; snprintf(filename, sizeof filename, "%s/%s_dri.so", From 51f353d0a0d116af16d7d9590cadef6c56328746 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 28 Feb 2011 13:10:20 -0500 Subject: [PATCH 09/16] dix: Fix ATOM typedef unsigned long is needlessly large on LP64. Use uint32_t instead. Reviewed-by: Daniel Stone Signed-off-by: Adam Jackson --- include/misc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/misc.h b/include/misc.h index b0abf9ac9..803f5bade 100644 --- a/include/misc.h +++ b/include/misc.h @@ -79,6 +79,7 @@ OF THIS SOFTWARE. #include #include +#include #ifndef MAXSCREENS #define MAXSCREENS 16 @@ -91,7 +92,7 @@ OF THIS SOFTWARE. #define EXTENSION_EVENT_BASE 64 #define EXTENSION_BASE 128 -typedef unsigned long ATOM; +typedef uint32_t ATOM; #ifndef TRUE #define TRUE 1 From 1f2bc777f96fd41feb55a4799ece939652130ef4 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 28 Feb 2011 13:11:12 -0500 Subject: [PATCH 10/16] dix: Shrink PropertyRec on LP64 size needn't be a long. No change on ILP32 but, combined with the previous change, 56 -> 40 bytes on LP64. Reviewed-by: Daniel Stone Signed-off-by: Adam Jackson --- include/propertyst.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/propertyst.h b/include/propertyst.h index fd1148eb7..1edd11d5d 100644 --- a/include/propertyst.h +++ b/include/propertyst.h @@ -58,8 +58,8 @@ typedef struct _Property { struct _Property *next; ATOM propertyName; ATOM type; /* ignored by server */ - short format; /* format of data for swapping - 8,16,32 */ - long size; /* size of data in (format/8) bytes */ + uint32_t format; /* format of data for swapping - 8,16,32 */ + uint32_t size; /* size of data in (format/8) bytes */ pointer data; /* private to client */ PrivateRec *devPrivates; } PropertyRec; From 016edc17512ba966d60edede8cf947996bae0b3c Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 28 Feb 2011 17:12:26 -0500 Subject: [PATCH 11/16] dix: Define RESTYPE as uint32_t long is needlessly long on LP64. Reviewed-by: Dave Airlie Reviewed-by: Daniel Stone Signed-off-by: Adam Jackson --- include/resource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/resource.h b/include/resource.h index 763aa99d9..772b7b877 100644 --- a/include/resource.h +++ b/include/resource.h @@ -56,7 +56,7 @@ SOFTWARE. /* classes for Resource routines */ -typedef unsigned long RESTYPE; +typedef uint32_t RESTYPE; #define RC_VANILLA ((RESTYPE)0) #define RC_CACHED ((RESTYPE)1<<31) From 57b35adaed112520c3b3b2fbad13cf5a91cd6652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Wed, 9 Mar 2011 13:57:25 -0500 Subject: [PATCH 12/16] Remove geometry arguments from miSourceValidate() The only user of the geometry coordinates is the software sprite code, which uses them to remove the pointer whenever the window beneath is being used as a source. However, using Window pictures as a source is extremely rare (let alone *partial* windows), so there is no harm done in just validating all of the drawable. Additionally, the miSourceValidate() function was buggy in at least three respects: (a) It added drawable->{x,y} before calling down, which is wrong since the misprite code already adds them in its check. (Alternatively, the misprite code is wrong, but there are actual users who would notice if that code was broken). (b) It didn't account for the width of the interpolation filter, so if the Picture had a bilinear or convolution filter, the edges surrounding the source area would not be validated. (c) It didn't validate alpha maps. Finally, computing the bounding box of the transform on every composite request was a real performance issue in pixman, so presumably it could be one here as well. This patch changes miSourceValidate() to simply validate all of the underlying drawable. Reviewed-by: Adam Jackson Reviewed-by: Keith Packard Signed-off-by: Soren Sandmann --- fb/fbpict.c | 4 ++-- render/mipict.c | 62 ++++++++++++------------------------------------- render/mipict.h | 7 ++---- 3 files changed, 19 insertions(+), 54 deletions(-) diff --git a/fb/fbpict.c b/fb/fbpict.c index 312f3df21..133f4226c 100644 --- a/fb/fbpict.c +++ b/fb/fbpict.c @@ -54,9 +54,9 @@ fbComposite (CARD8 op, int msk_xoff, msk_yoff; int dst_xoff, dst_yoff; - miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height); + miCompositeSourceValidate (pSrc); if (pMask) - miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height); + miCompositeSourceValidate (pMask); src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff); mask = image_from_pict (pMask, FALSE, &msk_xoff, &msk_yoff); diff --git a/render/mipict.c b/render/mipict.c index 3b7388879..a057840df 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -333,12 +333,8 @@ miClipPictureSrc (RegionPtr pRegion, return TRUE; } -void -miCompositeSourceValidate (PicturePtr pPicture, - INT16 x, - INT16 y, - CARD16 width, - CARD16 height) +static void +SourceValidateOnePicture (PicturePtr pPicture) { DrawablePtr pDrawable = pPicture->pDrawable; ScreenPtr pScreen; @@ -347,50 +343,22 @@ miCompositeSourceValidate (PicturePtr pPicture, return; pScreen = pDrawable->pScreen; - + if (pScreen->SourceValidate) { - if (pPicture->transform) - { - xPoint points[4]; - int i; - int xmin, ymin, xmax, ymax; - -#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; } - VectorSet (0, x, y); - VectorSet (1, x + width, y); - VectorSet (2, x, y + height); - VectorSet (3, x + width, y + height); - xmin = ymin = 32767; - xmax = ymax = -32737; - for (i = 0; i < 4; i++) - { - PictVector t; - t.vector[0] = IntToxFixed (points[i].x); - t.vector[1] = IntToxFixed (points[i].y); - t.vector[2] = xFixed1; - if (pixman_transform_point (pPicture->transform, &t)) - { - int tx = xFixedToInt (t.vector[0]); - int ty = xFixedToInt (t.vector[1]); - if (tx < xmin) xmin = tx; - if (tx > xmax) xmax = tx; - if (ty < ymin) ymin = ty; - if (ty > ymax) ymax = ty; - } - } - x = xmin; - y = ymin; - width = xmax - xmin; - height = ymax - ymin; - } - x += pPicture->pDrawable->x; - y += pPicture->pDrawable->y; - (*pScreen->SourceValidate) (pDrawable, x, y, width, height, - pPicture->subWindowMode); + pScreen->SourceValidate ( + pDrawable, 0, 0, pDrawable->width, pDrawable->height, pPicture->subWindowMode); } } +void +miCompositeSourceValidate (PicturePtr pPicture) +{ + SourceValidateOnePicture (pPicture); + if (pPicture->alphaMap) + SourceValidateOnePicture (pPicture->alphaMap); +} + /* * returns FALSE if the final region is empty. Indistinguishable from * an allocation failure, but rendering ignores those anyways. @@ -480,9 +448,9 @@ miComputeCompositeRegion (RegionPtr pRegion, } - miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height); + miCompositeSourceValidate (pSrc); if (pMask) - miCompositeSourceValidate (pMask, xMask, yMask, width, height); + miCompositeSourceValidate (pMask); return TRUE; } diff --git a/render/mipict.h b/render/mipict.h index d1495891e..a70db2417 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -81,11 +81,8 @@ miChangePictureFilter (PicturePtr pPicture, int nparams); extern _X_EXPORT void -miCompositeSourceValidate (PicturePtr pPicture, - INT16 x, - INT16 y, - CARD16 width, - CARD16 height); +miCompositeSourceValidate (PicturePtr pPicture); + extern _X_EXPORT Bool miComputeCompositeRegion (RegionPtr pRegion, PicturePtr pSrc, From f985a7319ef80b9b613eeaf24581000827cb220f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erkki=20Sepp=C3=A4l=C3=A4?= Date: Wed, 9 Mar 2011 17:29:14 +0200 Subject: [PATCH 13/16] mi/misprite: use memory management provided by dixRegisterPrivateKey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The record allocated by miSpriteDeviceCursorInitialize was not being released. This patch makes misprite use dixRegisterPrivateKey with the record size argument, which handles the memory management issues. miSpriteDeviceCursorInitialize is restructured to initialize pCursorInfo only if miDCDeviceInitialize succeeds. The record itself is zeroed on cleanup to ensure that the assumptions in the code still hold. Reviewed-by: Daniel Stone Reviewed-by: Rami Ylimäki Signed-off-by: Erkki Seppälä --- mi/misprite.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/mi/misprite.c b/mi/misprite.c index b0290af29..1cfcdf6ee 100644 --- a/mi/misprite.c +++ b/mi/misprite.c @@ -308,7 +308,7 @@ miSpriteInitialize (ScreenPtr pScreen, if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) return FALSE; - if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, 0)) + if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec))) return FALSE; pScreenPriv = malloc(sizeof (miSpriteScreenRec)); @@ -860,38 +860,35 @@ miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) static Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) { - miCursorInfoPtr pCursorInfo; - int ret = FALSE; + int ret = miDCDeviceInitialize(pDev, pScreen); - pCursorInfo = malloc(sizeof(miCursorInfoRec)); - if (!pCursorInfo) - return FALSE; - - pCursorInfo->pCursor = NULL; - pCursorInfo->x = 0; - pCursorInfo->y = 0; - pCursorInfo->isUp = FALSE; - pCursorInfo->shouldBeUp = FALSE; - pCursorInfo->pCacheWin = NullWindow; - pCursorInfo->isInCacheWin = FALSE; - pCursorInfo->checkPixels = TRUE; - pCursorInfo->pScreen = FALSE; - - ret = miDCDeviceInitialize(pDev, pScreen); - if (!ret) + if (ret) { - free(pCursorInfo); - pCursorInfo = NULL; + miCursorInfoPtr pCursorInfo; + pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); + pCursorInfo->pCursor = NULL; + pCursorInfo->x = 0; + pCursorInfo->y = 0; + pCursorInfo->isUp = FALSE; + pCursorInfo->shouldBeUp = FALSE; + pCursorInfo->pCacheWin = NullWindow; + pCursorInfo->isInCacheWin = FALSE; + pCursorInfo->checkPixels = TRUE; + pCursorInfo->pScreen = FALSE; } - dixSetPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey, pCursorInfo); + return ret; } static void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) { + miCursorInfoPtr pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); + if (DevHasCursor(pDev)) miDCDeviceCleanup(pDev, pScreen); + + memset(pCursorInfo, 0, sizeof(miCursorInfoRec)); } /* From c2af0cea02bd85f4d5954c16e34b4a8fb0fe2243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Tue, 8 Mar 2011 10:14:26 -0500 Subject: [PATCH 14/16] Absorb miTriFan() into CompositeTriFan() There is no need to virtualize this function that nobody cares about. Reviewed-by: Adam Jackson Acked-by: Keith Packard Signed-off-by: Soren Sandmann --- render/mitri.c | 21 --------------------- render/picture.c | 23 +++++++++++++++++++---- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/render/mitri.c b/render/mitri.c index b258c2156..c74192c1a 100644 --- a/render/mitri.c +++ b/render/mitri.c @@ -108,25 +108,4 @@ miTriFan (CARD8 op, int npoint, xPointFixed *points) { - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - xTriangle *tris, *tri; - xPointFixed *first; - int ntri; - - if (npoint < 3) - return; - ntri = npoint - 2; - tris = malloc(ntri * sizeof (xTriangle)); - if (!tris) - return; - first = points++; - for (tri = tris; npoint >= 3; npoint--, points++, tri++) - { - tri->p1 = *first; - tri->p2 = points[0]; - tri->p3 = points[1]; - } - (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); - free(tris); } diff --git a/render/picture.c b/render/picture.c index 0028cc76a..e16163ac7 100644 --- a/render/picture.c +++ b/render/picture.c @@ -1790,11 +1790,26 @@ CompositeTriFan (CARD8 op, int npoints, xPointFixed *points) { - PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + ScreenPtr pScreen = pDst->pDrawable->pScreen; + xTriangle *tris, *tri; + xPointFixed *first; + int ntri; - ValidatePicture (pSrc); - ValidatePicture (pDst); - (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points); + if (npoints < 3) + return; + ntri = npoints - 2; + tris = malloc(ntri * sizeof (xTriangle)); + if (!tris) + return; + first = points++; + for (tri = tris; npoints >= 3; npoints--, points++, tri++) + { + tri->p1 = *first; + tri->p2 = points[0]; + tri->p3 = points[1]; + } + CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); + free(tris); } void From 0eb5b0fbcf1233a93f285ff1e1609fcbd01e7c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Tue, 8 Mar 2011 10:14:27 -0500 Subject: [PATCH 15/16] Absorb miTriStrip() into CompositeTriStrip() There is no need to virtualize this function that nobody cares about. Reviewed-by: Adam Jackson Acked-by: Keith Packard Signed-off-by: Soren Sandmann --- render/mitri.c | 19 ------------------- render/picture.c | 22 ++++++++++++++++++---- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/render/mitri.c b/render/mitri.c index c74192c1a..2ca7cc4d7 100644 --- a/render/mitri.c +++ b/render/mitri.c @@ -77,25 +77,6 @@ miTriStrip (CARD8 op, int npoint, xPointFixed *points) { - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - xTriangle *tris, *tri; - int ntri; - - if (npoint < 3) - return; - ntri = npoint - 2; - tris = malloc(ntri * sizeof (xTriangle)); - if (!tris) - return; - for (tri = tris; npoint >= 3; npoint--, points++, tri++) - { - tri->p1 = points[0]; - tri->p2 = points[1]; - tri->p3 = points[2]; - } - (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); - free(tris); } void diff --git a/render/picture.c b/render/picture.c index e16163ac7..015d63364 100644 --- a/render/picture.c +++ b/render/picture.c @@ -1773,11 +1773,25 @@ CompositeTriStrip (CARD8 op, int npoints, xPointFixed *points) { - PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + xTriangle *tris, *tri; + int ntri; - ValidatePicture (pSrc); - ValidatePicture (pDst); - (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points); + if (npoints < 3) + return; + ntri = npoints - 2; + tris = malloc(ntri * sizeof (xTriangle)); + if (!tris) + return; + for (tri = tris; npoints >= 3; npoints--, points++, tri++) + { + tri->p1 = points[0]; + tri->p2 = points[1]; + tri->p3 = points[2]; + } + CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); + free(tris); } void From d7f8011418f9da06631f27c66c29bcb226d0dffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Tue, 8 Mar 2011 10:14:28 -0500 Subject: [PATCH 16/16] Remove TriStrip and TriFan from the picture screen These functions no longer go through the screen vtable, so remove them and fix up the various wrappers. Reviewed-by: Adam Jackson Acked-by: Keith Packard Signed-off-by: Soren Sandmann --- hw/dmx/dmx.h | 2 - hw/dmx/dmxpict.c | 87 -------------------------------------------- hw/dmx/dmxpict.h | 10 ----- miext/cw/cw.h | 2 - miext/cw/cw_render.c | 64 -------------------------------- render/mipict.c | 2 - render/mipict.h | 20 ---------- render/mitri.c | 24 ------------ render/picturestr.h | 2 - 9 files changed, 213 deletions(-) diff --git a/hw/dmx/dmx.h b/hw/dmx/dmx.h index bf4b92cb2..c6b6199a5 100644 --- a/hw/dmx/dmx.h +++ b/hw/dmx/dmx.h @@ -249,8 +249,6 @@ typedef struct _DMXScreenInfo { TrapezoidsProcPtr Trapezoids; TrianglesProcPtr Triangles; - TriStripProcPtr TriStrip; - TriFanProcPtr TriFan; } DMXScreenInfo; /* Global variables available to all Xserver/hw/dmx routines. */ diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c index bbde8fde1..1fb54620a 100644 --- a/hw/dmx/dmxpict.c +++ b/hw/dmx/dmxpict.c @@ -165,8 +165,6 @@ Bool dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps); DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps); - DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps); - DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps); return TRUE; } @@ -1237,88 +1235,3 @@ void dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps); } - -/** Composite a triangle strip on the appropriate screen. For a - * complete description see the protocol document of the RENDER - * library. */ -void dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, - int npoint, xPointFixed *points) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - PictureScreenPtr ps = GetPictureScreen(pScreen); - dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); - dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); - - DMX_UNWRAP(TriStrip, dmxScreen, ps); -#if 0 - if (ps->TriStrip) - ps->TriStrip(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points); -#endif - - /* Draw trapezoids on back-end server */ - if (pDstPriv->pict) { - XRenderPictFormat *pFormat; - - pFormat = dmxFindFormat(dmxScreen, maskFormat); - if (!pFormat) { - /* FIXME: Error! */ - } - - XRenderCompositeTriStrip(dmxScreen->beDisplay, - op, - pSrcPriv->pict, - pDstPriv->pict, - pFormat, - xSrc, ySrc, - (XPointFixed *)points, - npoint); - dmxSync(dmxScreen, FALSE); - } - - DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps); -} - -/** Composite a triangle fan on the appropriate screen. For a complete - * description see the protocol document of the RENDER library. */ -void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, - int npoint, xPointFixed *points) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - PictureScreenPtr ps = GetPictureScreen(pScreen); - dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); - dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); - - DMX_UNWRAP(TriFan, dmxScreen, ps); -#if 0 - if (ps->TriFan) - ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points); -#endif - - /* Draw trapezoids on back-end server */ - if (pDstPriv->pict) { - XRenderPictFormat *pFormat; - - pFormat = dmxFindFormat(dmxScreen, maskFormat); - if (!pFormat) { - /* FIXME: Error! */ - } - - XRenderCompositeTriFan(dmxScreen->beDisplay, - op, - pSrcPriv->pict, - pDstPriv->pict, - pFormat, - xSrc, ySrc, - (XPointFixed *)points, - npoint); - dmxSync(dmxScreen, FALSE); - } - - DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps); -} diff --git a/hw/dmx/dmxpict.h b/hw/dmx/dmxpict.h index 3c8a09ce4..a732991e4 100644 --- a/hw/dmx/dmxpict.h +++ b/hw/dmx/dmxpict.h @@ -100,16 +100,6 @@ extern void dmxTriangles(CARD8 op, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntri, xTriangle *tris); -extern void dmxTriStrip(CARD8 op, - PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, - int npoint, xPointFixed *points); -extern void dmxTriFan(CARD8 op, - PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, - int npoint, xPointFixed *points); extern int dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet); extern Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet); diff --git a/miext/cw/cw.h b/miext/cw/cw.h index 31eb9e57c..e2bb9ad88 100644 --- a/miext/cw/cw.h +++ b/miext/cw/cw.h @@ -106,8 +106,6 @@ typedef struct { TrapezoidsProcPtr Trapezoids; TrianglesProcPtr Triangles; - TriStripProcPtr TriStrip; - TriFanProcPtr TriFan; RasterizeTrapezoidProcPtr RasterizeTrapezoid; } cwScreenRec, *cwScreenPtr; diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c index 165c44f46..1f990aefa 100644 --- a/miext/cw/cw_render.c +++ b/miext/cw/cw_render.c @@ -371,66 +371,6 @@ cwTriangles (CARD8 op, cwPsWrap(Triangles, cwTriangles); } -static void -cwTriStrip (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - int i; - - cwPsUnwrap(TriStrip); - if (dst_picture_x_off || dst_picture_y_off) { - for (i = 0; i < npoint; i++) - { - points[i].x += dst_picture_x_off << 16; - points[i].y += dst_picture_y_off << 16; - } - } - (*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - npoint, points); - cwPsWrap(TriStrip, cwTriStrip); -} - -static void -cwTriFan (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - int i; - - cwPsUnwrap(TriFan); - if (dst_picture_x_off || dst_picture_y_off) { - for (i = 0; i < npoint; i++) - { - points[i].x += dst_picture_x_off << 16; - points[i].y += dst_picture_y_off << 16; - } - } - (*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - npoint, points); - cwPsWrap(TriFan, cwTriFan); -} - void cwInitializeRender (ScreenPtr pScreen) { @@ -443,8 +383,6 @@ cwInitializeRender (ScreenPtr pScreen) cwPsWrap(CompositeRects, cwCompositeRects); cwPsWrap(Trapezoids, cwTrapezoids); cwPsWrap(Triangles, cwTriangles); - cwPsWrap(TriStrip, cwTriStrip); - cwPsWrap(TriFan, cwTriFan); /* There is no need to wrap AddTraps as far as we can tell. AddTraps can * only be done on alpha-only pictures, and we won't be getting * alpha-only window pictures, so there's no need to translate. @@ -463,7 +401,5 @@ cwFiniRender (ScreenPtr pScreen) cwPsUnwrap(CompositeRects); cwPsUnwrap(Trapezoids); cwPsUnwrap(Triangles); - cwPsUnwrap(TriStrip); - cwPsUnwrap(TriFan); } diff --git a/render/mipict.c b/render/mipict.c index a057840df..08b2fa722 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -601,8 +601,6 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) ps->CompositeRects = miCompositeRects; ps->Trapezoids = 0; ps->Triangles = 0; - ps->TriStrip = miTriStrip; - ps->TriFan = miTriFan; ps->RasterizeTrapezoid = 0; /* requires DDX support */ ps->AddTraps = 0; /* requires DDX support */ diff --git a/render/mipict.h b/render/mipict.h index a70db2417..f6d9deefd 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -148,26 +148,6 @@ miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds); extern _X_EXPORT void miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds); -extern _X_EXPORT void -miTriStrip (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points); - -extern _X_EXPORT void -miTriFan (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points); - extern _X_EXPORT Bool miInitIndexed (ScreenPtr pScreen, PictFormatPtr pFormat); diff --git a/render/mitri.c b/render/mitri.c index 2ca7cc4d7..b322a7c62 100644 --- a/render/mitri.c +++ b/render/mitri.c @@ -66,27 +66,3 @@ miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds) { miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds); } - -void -miTriStrip (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points) -{ -} - -void -miTriFan (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points) -{ -} diff --git a/render/picturestr.h b/render/picturestr.h index ae69eef10..7c7edb1c4 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -381,8 +381,6 @@ typedef struct _PictureScreen { TrapezoidsProcPtr Trapezoids; TrianglesProcPtr Triangles; - TriStripProcPtr TriStrip; - TriFanProcPtr TriFan; RasterizeTrapezoidProcPtr RasterizeTrapezoid;