105b261ecSmrg/*
235c4bbdfSmrg * Copyright © 2006 Intel Corporation
305b261ecSmrg *
405b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
505b261ecSmrg * copy of this software and associated documentation files (the "Software"),
605b261ecSmrg * to deal in the Software without restriction, including without limitation
705b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
805b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
905b261ecSmrg * Software is furnished to do so, subject to the following conditions:
1005b261ecSmrg *
1105b261ecSmrg * The above copyright notice and this permission notice (including the next
1205b261ecSmrg * paragraph) shall be included in all copies or substantial portions of the
1305b261ecSmrg * Software.
1405b261ecSmrg *
1505b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1605b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1705b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1805b261ecSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1905b261ecSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2005b261ecSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2105b261ecSmrg * SOFTWARE.
2205b261ecSmrg *
2305b261ecSmrg * Authors:
2405b261ecSmrg *    Eric Anholt <anholt@FreeBSD.org>
2505b261ecSmrg *
2605b261ecSmrg */
2705b261ecSmrg
281b5d61b8Smrg#ifdef HAVE_XORG_CONFIG_H
2905b261ecSmrg#include <xorg-config.h>
3005b261ecSmrg#endif
3105b261ecSmrg
3205b261ecSmrg#include <string.h>
3305b261ecSmrg
3405b261ecSmrg#include "exa_priv.h"
3505b261ecSmrg
3605b261ecSmrg#include "xf86str.h"
3705b261ecSmrg#include "xf86.h"
3805b261ecSmrg
3905b261ecSmrgtypedef struct _ExaXorgScreenPrivRec {
4035c4bbdfSmrg    CloseScreenProcPtr SavedCloseScreen;
4135c4bbdfSmrg    xf86EnableDisableFBAccessProc *SavedEnableDisableFBAccess;
4235c4bbdfSmrg    OptionInfoPtr options;
4305b261ecSmrg} ExaXorgScreenPrivRec, *ExaXorgScreenPrivPtr;
4405b261ecSmrg
456747b715Smrgstatic DevPrivateKeyRec exaXorgScreenPrivateKeyRec;
4635c4bbdfSmrg
476747b715Smrg#define exaXorgScreenPrivateKey (&exaXorgScreenPrivateKeyRec)
4805b261ecSmrg
4905b261ecSmrgtypedef enum {
5005b261ecSmrg    EXAOPT_MIGRATION_HEURISTIC,
5105b261ecSmrg    EXAOPT_NO_COMPOSITE,
5205b261ecSmrg    EXAOPT_NO_UTS,
5305b261ecSmrg    EXAOPT_NO_DFS,
544642e01fSmrg    EXAOPT_OPTIMIZE_MIGRATION
5505b261ecSmrg} EXAOpts;
5605b261ecSmrg
5705b261ecSmrgstatic const OptionInfoRec EXAOptions[] = {
5835c4bbdfSmrg    {EXAOPT_MIGRATION_HEURISTIC, "MigrationHeuristic",
5935c4bbdfSmrg     OPTV_ANYSTR, {0}, FALSE},
6035c4bbdfSmrg    {EXAOPT_NO_COMPOSITE, "EXANoComposite",
6135c4bbdfSmrg     OPTV_BOOLEAN, {0}, FALSE},
6235c4bbdfSmrg    {EXAOPT_NO_UTS, "EXANoUploadToScreen",
6335c4bbdfSmrg     OPTV_BOOLEAN, {0}, FALSE},
6435c4bbdfSmrg    {EXAOPT_NO_DFS, "EXANoDownloadFromScreen",
6535c4bbdfSmrg     OPTV_BOOLEAN, {0}, FALSE},
6635c4bbdfSmrg    {EXAOPT_OPTIMIZE_MIGRATION, "EXAOptimizeMigration",
6735c4bbdfSmrg     OPTV_BOOLEAN, {0}, FALSE},
6835c4bbdfSmrg    {-1, NULL,
6935c4bbdfSmrg     OPTV_NONE, {0}, FALSE}
7005b261ecSmrg};
7105b261ecSmrg
7205b261ecSmrgstatic Bool
7335c4bbdfSmrgexaXorgCloseScreen(ScreenPtr pScreen)
7405b261ecSmrg{
7535c4bbdfSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
764642e01fSmrg    ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
7735c4bbdfSmrg        dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
7805b261ecSmrg
7905b261ecSmrg    pScreen->CloseScreen = pScreenPriv->SavedCloseScreen;
8005b261ecSmrg
8105b261ecSmrg    pScrn->EnableDisableFBAccess = pScreenPriv->SavedEnableDisableFBAccess;
8205b261ecSmrg
836747b715Smrg    free(pScreenPriv->options);
846747b715Smrg    free(pScreenPriv);
8505b261ecSmrg
8635c4bbdfSmrg    return pScreen->CloseScreen(pScreen);
8705b261ecSmrg}
8805b261ecSmrg
8905b261ecSmrgstatic void
9035c4bbdfSmrgexaXorgEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable)
9105b261ecSmrg{
9235c4bbdfSmrg    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
934642e01fSmrg    ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
9435c4bbdfSmrg        dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
9505b261ecSmrg
9605b261ecSmrg    if (!enable)
9735c4bbdfSmrg        exaEnableDisableFBAccess(pScreen, enable);
9805b261ecSmrg
9905b261ecSmrg    if (pScreenPriv->SavedEnableDisableFBAccess)
10035c4bbdfSmrg        pScreenPriv->SavedEnableDisableFBAccess(pScrn, enable);
10105b261ecSmrg
10205b261ecSmrg    if (enable)
10335c4bbdfSmrg        exaEnableDisableFBAccess(pScreen, enable);
10405b261ecSmrg}
10505b261ecSmrg
10605b261ecSmrg/**
10705b261ecSmrg * This will be called during exaDriverInit, giving us the chance to set options
10805b261ecSmrg * and hook in our EnableDisableFBAccess.
10905b261ecSmrg */
11005b261ecSmrgvoid
11105b261ecSmrgexaDDXDriverInit(ScreenPtr pScreen)
11205b261ecSmrg{
11305b261ecSmrg    ExaScreenPriv(pScreen);
11435c4bbdfSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
11505b261ecSmrg    ExaXorgScreenPrivPtr pScreenPriv;
11605b261ecSmrg
1176747b715Smrg    if (!dixRegisterPrivateKey(&exaXorgScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
11835c4bbdfSmrg        return;
1196747b715Smrg
1206747b715Smrg    pScreenPriv = calloc(1, sizeof(ExaXorgScreenPrivRec));
12105b261ecSmrg    if (pScreenPriv == NULL)
12235c4bbdfSmrg        return;
12305b261ecSmrg
12435c4bbdfSmrg    pScreenPriv->options = xnfalloc(sizeof(EXAOptions));
12505b261ecSmrg    memcpy(pScreenPriv->options, EXAOptions, sizeof(EXAOptions));
12635c4bbdfSmrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pScreenPriv->options);
12705b261ecSmrg
1286747b715Smrg    if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
12935c4bbdfSmrg        if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
13035c4bbdfSmrg            pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
13135c4bbdfSmrg            const char *heuristicName;
13235c4bbdfSmrg
13335c4bbdfSmrg            heuristicName = xf86GetOptValString(pScreenPriv->options,
13435c4bbdfSmrg                                                EXAOPT_MIGRATION_HEURISTIC);
13535c4bbdfSmrg            if (heuristicName != NULL) {
13635c4bbdfSmrg                if (strcmp(heuristicName, "greedy") == 0)
13735c4bbdfSmrg                    pExaScr->migration = ExaMigrationGreedy;
13835c4bbdfSmrg                else if (strcmp(heuristicName, "always") == 0)
13935c4bbdfSmrg                    pExaScr->migration = ExaMigrationAlways;
14035c4bbdfSmrg                else if (strcmp(heuristicName, "smart") == 0)
14135c4bbdfSmrg                    pExaScr->migration = ExaMigrationSmart;
14235c4bbdfSmrg                else {
14335c4bbdfSmrg                    xf86DrvMsg(pScreen->myNum, X_WARNING,
14435c4bbdfSmrg                               "EXA: unknown migration heuristic %s\n",
14535c4bbdfSmrg                               heuristicName);
14635c4bbdfSmrg                }
14735c4bbdfSmrg            }
14835c4bbdfSmrg        }
14935c4bbdfSmrg
15035c4bbdfSmrg        pExaScr->optimize_migration =
15135c4bbdfSmrg            xf86ReturnOptValBool(pScreenPriv->options,
15235c4bbdfSmrg                                 EXAOPT_OPTIMIZE_MIGRATION, TRUE);
15305b261ecSmrg    }
15405b261ecSmrg
15535c4bbdfSmrg    if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_COMPOSITE, FALSE)) {
15635c4bbdfSmrg        xf86DrvMsg(pScreen->myNum, X_CONFIG,
15735c4bbdfSmrg                   "EXA: Disabling Composite operation "
15835c4bbdfSmrg                   "(RENDER acceleration)\n");
15935c4bbdfSmrg        pExaScr->info->CheckComposite = NULL;
16035c4bbdfSmrg        pExaScr->info->PrepareComposite = NULL;
16105b261ecSmrg    }
16205b261ecSmrg
1634642e01fSmrg    if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_UTS, FALSE)) {
16435c4bbdfSmrg        xf86DrvMsg(pScreen->myNum, X_CONFIG, "EXA: Disabling UploadToScreen\n");
16535c4bbdfSmrg        pExaScr->info->UploadToScreen = NULL;
16605b261ecSmrg    }
16705b261ecSmrg
1684642e01fSmrg    if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_DFS, FALSE)) {
16935c4bbdfSmrg        xf86DrvMsg(pScreen->myNum, X_CONFIG,
17035c4bbdfSmrg                   "EXA: Disabling DownloadFromScreen\n");
17135c4bbdfSmrg        pExaScr->info->DownloadFromScreen = NULL;
17205b261ecSmrg    }
17305b261ecSmrg
1744642e01fSmrg    dixSetPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey, pScreenPriv);
17505b261ecSmrg
17605b261ecSmrg    pScreenPriv->SavedEnableDisableFBAccess = pScrn->EnableDisableFBAccess;
17705b261ecSmrg    pScrn->EnableDisableFBAccess = exaXorgEnableDisableFBAccess;
17835c4bbdfSmrg
17905b261ecSmrg    pScreenPriv->SavedCloseScreen = pScreen->CloseScreen;
18005b261ecSmrg    pScreen->CloseScreen = exaXorgCloseScreen;
18135c4bbdfSmrg
18205b261ecSmrg}
18305b261ecSmrg
18435c4bbdfSmrgstatic XF86ModuleVersionInfo exaVersRec = {
18535c4bbdfSmrg    "exa",
18635c4bbdfSmrg    MODULEVENDORSTRING,
18735c4bbdfSmrg    MODINFOSTRING1,
18835c4bbdfSmrg    MODINFOSTRING2,
18935c4bbdfSmrg    XORG_VERSION_CURRENT,
19035c4bbdfSmrg    EXA_VERSION_MAJOR, EXA_VERSION_MINOR, EXA_VERSION_RELEASE,
19135c4bbdfSmrg    ABI_CLASS_VIDEODRV,         /* requires the video driver ABI */
19235c4bbdfSmrg    ABI_VIDEODRV_VERSION,
19335c4bbdfSmrg    MOD_CLASS_NONE,
19435c4bbdfSmrg    {0, 0, 0, 0}
19505b261ecSmrg};
19605b261ecSmrg
1974642e01fSmrg_X_EXPORT XF86ModuleData exaModuleData = { &exaVersRec, NULL, NULL };
198