[RFC PATCH] randr: crtc cursor confinement

Mikhail Gusarov dottedmag at dottedmag.net
Tue Oct 12 12:22:09 PDT 2010


Twas brillig at 14:36:49 12.10.2010 UTC-04 when ajax at redhat.com did gyre and gimble:

 AJ> +/*
 AJ> + * This isn't really multiplication, but we don't need it to be.  All
 AJ> + * we need is a boolean for connectivity, not an integer for number of
 AJ> + * paths.  As a result we can scale to gratuitously large n without
 AJ> + * worrying about integer overflow.
 AJ> + */
 AJ> +static Bool
 AJ> +matrix_pseudomultiply(char *left, const char *right, int n)
 AJ> +{
 AJ> +    int i, j, k;
 AJ> +    char *res = calloc(1, n * n);
 AJ> +
 AJ> +    if (!res)
 AJ> +        return FALSE;
 AJ> +
 AJ> +    for (i = 0; i < n; i++)
 AJ> +        for (j = 0; j < n; j++)
 AJ> +            for (k = 0; k < n; k++)
 AJ> +                res[i*n + j] |= left[i*n + k] && right[k*n + j];
 AJ> +
 AJ> +    memcpy(left, res, n * n);
 AJ> +
 AJ> +    free(res);
 AJ> +
 AJ> +    return TRUE;
 AJ> +}
 AJ> +
 AJ> +static void
 AJ> +RRComputeContiguity (ScreenPtr pScreen)
 AJ> +{
 AJ> +    rrScrPriv(pScreen);
 AJ> +    Bool discontiguous = TRUE;
 AJ> +    int i, j, n = pScrPriv->numCrtcs;
 AJ> +    RRCrtcPtr a, b;
 AJ> +    char *matrix = NULL, *m = NULL;
 AJ> +
 AJ> +    matrix = calloc(1, n*n);
 AJ> +    m = calloc(1, n*n);
 AJ> +    if (!matrix || !m)
 AJ> +        goto out;
 AJ> +
 AJ> +    /* compute adjacency matrix; everything is adjacent with itself */
 AJ> +    for (i = 0; i < n; i++) {
 AJ> +        a = pScrPriv->crtcs[i];
 AJ> +
 AJ> +        if (!a->mode)
 AJ> +            continue;
 AJ> +
 AJ> +        for (j = 0; j < n; j++) {
 AJ> +            b = pScrPriv->crtcs[j];
 AJ> +
 AJ> +            if (!b->mode)
 AJ> +                continue;
 AJ> +
 AJ> +            if (a == b || crtcs_adjacent(a, b))
 AJ> +                matrix[i*n + j] = 1;
 AJ> +        }
 AJ> +    }
 AJ> +
 AJ> +    memcpy(m, matrix, n*n);
 AJ> +
 AJ> +    /* raise it to the n-1th; finds connected paths */
 AJ> +    for (i = 0; i < n-1; i++)
 AJ> +        if (!matrix_pseudomultiply(m, matrix, n))
 AJ> +            goto out;
 AJ> +
 AJ> +    /* check for connectivity */
 AJ> +    for (i = 0; i < n; i++)
 AJ> +        if (pScrPriv->crtcs[i]->mode && !m[i])
 AJ> +            goto out;
 AJ> +
 AJ> +    discontiguous = FALSE;
 AJ> +
 AJ> +out:
 AJ> +    free(matrix);
 AJ> +    free(m);
 AJ> +    pScrPriv->discontiguous = discontiguous;
 AJ> +}

Isn't it too indirect? Just scratched the following (not even
compile-tested). If recursion is a no-no due to systems with numCrtcs >
100k, then recursion is easily rewritten to queue.

/* Depth-first search and mark all CRTCs reachable from cur */
static void
dfs (rrScrPrivPtr pScrPriv, int *reachable, int cur)
{
    int i;
    reachable[cur] = TRUE;
    for (i = 0; i < pScrPriv->numCrtcs; ++i) {
        if (reachable[i])
            continue;
        if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
            dfs(pScrPriv, reachable, i);
    }
}

static void
RRComputeContiguity (ScreenPtr pScreen)
{
    rrScrPriv(pScreen);
    Bool discontiguous = TRUE;
    int i, n = pScrPriv->numCrtcs;

    int *reachable = calloc(1, n);
    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) {
            dfs(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;
}

-- 
  http://fossarchy.blogspot.com/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg-devel/attachments/20101012/8a903471/attachment.pgp>


More information about the xorg-devel mailing list