1 /*
2  * Copyright © 2006 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <anholt@FreeBSD.org>
25  *
26  */
27 
28 #ifdef HAVE_XORG_CONFIG_H
29 #include <xorg-config.h>
30 #endif
31 
32 #include <string.h>
33 
34 #include "exa_priv.h"
35 
36 #include "xf86str.h"
37 #include "xf86.h"
38 
39 typedef struct _ExaXorgScreenPrivRec {
40     CloseScreenProcPtr SavedCloseScreen;
41     xf86EnableDisableFBAccessProc *SavedEnableDisableFBAccess;
42     OptionInfoPtr options;
43 } ExaXorgScreenPrivRec, *ExaXorgScreenPrivPtr;
44 
45 static DevPrivateKeyRec exaXorgScreenPrivateKeyRec;
46 
47 #define exaXorgScreenPrivateKey (&exaXorgScreenPrivateKeyRec)
48 
49 typedef enum {
50     EXAOPT_MIGRATION_HEURISTIC,
51     EXAOPT_NO_COMPOSITE,
52     EXAOPT_NO_UTS,
53     EXAOPT_NO_DFS,
54     EXAOPT_OPTIMIZE_MIGRATION
55 } EXAOpts;
56 
57 static const OptionInfoRec EXAOptions[] = {
58     {EXAOPT_MIGRATION_HEURISTIC, "MigrationHeuristic",
59      OPTV_ANYSTR, {0}, FALSE},
60     {EXAOPT_NO_COMPOSITE, "EXANoComposite",
61      OPTV_BOOLEAN, {0}, FALSE},
62     {EXAOPT_NO_UTS, "EXANoUploadToScreen",
63      OPTV_BOOLEAN, {0}, FALSE},
64     {EXAOPT_NO_DFS, "EXANoDownloadFromScreen",
65      OPTV_BOOLEAN, {0}, FALSE},
66     {EXAOPT_OPTIMIZE_MIGRATION, "EXAOptimizeMigration",
67      OPTV_BOOLEAN, {0}, FALSE},
68     {-1, NULL,
69      OPTV_NONE, {0}, FALSE}
70 };
71 
72 static Bool
exaXorgCloseScreen(ScreenPtr pScreen)73 exaXorgCloseScreen(ScreenPtr pScreen)
74 {
75     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
76     ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
77         dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
78 
79     pScreen->CloseScreen = pScreenPriv->SavedCloseScreen;
80 
81     pScrn->EnableDisableFBAccess = pScreenPriv->SavedEnableDisableFBAccess;
82 
83     free(pScreenPriv->options);
84     free(pScreenPriv);
85 
86     return pScreen->CloseScreen(pScreen);
87 }
88 
89 static void
exaXorgEnableDisableFBAccess(ScrnInfoPtr pScrn,Bool enable)90 exaXorgEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable)
91 {
92     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
93     ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
94         dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
95 
96     if (!enable)
97         exaEnableDisableFBAccess(pScreen, enable);
98 
99     if (pScreenPriv->SavedEnableDisableFBAccess)
100         pScreenPriv->SavedEnableDisableFBAccess(pScrn, enable);
101 
102     if (enable)
103         exaEnableDisableFBAccess(pScreen, enable);
104 }
105 
106 /**
107  * This will be called during exaDriverInit, giving us the chance to set options
108  * and hook in our EnableDisableFBAccess.
109  */
110 void
exaDDXDriverInit(ScreenPtr pScreen)111 exaDDXDriverInit(ScreenPtr pScreen)
112 {
113     ExaScreenPriv(pScreen);
114     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
115     ExaXorgScreenPrivPtr pScreenPriv;
116 
117     if (!dixRegisterPrivateKey(&exaXorgScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
118         return;
119 
120     pScreenPriv = calloc(1, sizeof(ExaXorgScreenPrivRec));
121     if (pScreenPriv == NULL)
122         return;
123 
124     pScreenPriv->options = xnfalloc(sizeof(EXAOptions));
125     memcpy(pScreenPriv->options, EXAOptions, sizeof(EXAOptions));
126     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pScreenPriv->options);
127 
128     if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
129         if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
130             pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
131             const char *heuristicName;
132 
133             heuristicName = xf86GetOptValString(pScreenPriv->options,
134                                                 EXAOPT_MIGRATION_HEURISTIC);
135             if (heuristicName != NULL) {
136                 if (strcmp(heuristicName, "greedy") == 0)
137                     pExaScr->migration = ExaMigrationGreedy;
138                 else if (strcmp(heuristicName, "always") == 0)
139                     pExaScr->migration = ExaMigrationAlways;
140                 else if (strcmp(heuristicName, "smart") == 0)
141                     pExaScr->migration = ExaMigrationSmart;
142                 else {
143                     xf86DrvMsg(pScreen->myNum, X_WARNING,
144                                "EXA: unknown migration heuristic %s\n",
145                                heuristicName);
146                 }
147             }
148         }
149 
150         pExaScr->optimize_migration =
151             xf86ReturnOptValBool(pScreenPriv->options,
152                                  EXAOPT_OPTIMIZE_MIGRATION, TRUE);
153     }
154 
155     if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_COMPOSITE, FALSE)) {
156         xf86DrvMsg(pScreen->myNum, X_CONFIG,
157                    "EXA: Disabling Composite operation "
158                    "(RENDER acceleration)\n");
159         pExaScr->info->CheckComposite = NULL;
160         pExaScr->info->PrepareComposite = NULL;
161     }
162 
163     if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_UTS, FALSE)) {
164         xf86DrvMsg(pScreen->myNum, X_CONFIG, "EXA: Disabling UploadToScreen\n");
165         pExaScr->info->UploadToScreen = NULL;
166     }
167 
168     if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_DFS, FALSE)) {
169         xf86DrvMsg(pScreen->myNum, X_CONFIG,
170                    "EXA: Disabling DownloadFromScreen\n");
171         pExaScr->info->DownloadFromScreen = NULL;
172     }
173 
174     dixSetPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey, pScreenPriv);
175 
176     pScreenPriv->SavedEnableDisableFBAccess = pScrn->EnableDisableFBAccess;
177     pScrn->EnableDisableFBAccess = exaXorgEnableDisableFBAccess;
178 
179     pScreenPriv->SavedCloseScreen = pScreen->CloseScreen;
180     pScreen->CloseScreen = exaXorgCloseScreen;
181 
182 }
183 
184 static XF86ModuleVersionInfo exaVersRec = {
185     "exa",
186     MODULEVENDORSTRING,
187     MODINFOSTRING1,
188     MODINFOSTRING2,
189     XORG_VERSION_CURRENT,
190     EXA_VERSION_MAJOR, EXA_VERSION_MINOR, EXA_VERSION_RELEASE,
191     ABI_CLASS_VIDEODRV,         /* requires the video driver ABI */
192     ABI_VIDEODRV_VERSION,
193     MOD_CLASS_NONE,
194     {0, 0, 0, 0}
195 };
196 
197 _X_EXPORT XF86ModuleData exaModuleData = { &exaVersRec, NULL, NULL };
198