xf86DiDGA.c revision 05b261ec
1/*
2 * Copyright © 2006 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  The copyright holders make no representations
11 * about the suitability of this software for any purpose.  It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_XORG_CONFIG_H
24#include <xorg-config.h>
25#else
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29#endif
30
31#include "xf86.h"
32#include "xf86DDC.h"
33#include "xf86_OSproc.h"
34#include "dgaproc.h"
35#include "xf86Crtc.h"
36#include "xf86Modes.h"
37#include "gcstruct.h"
38#include "scrnintstr.h"
39#include "windowstr.h"
40
41static Bool
42xf86_dga_get_modes (ScreenPtr pScreen)
43{
44    ScrnInfoPtr		scrn = xf86Screens[pScreen->myNum];
45    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
46    DGAModePtr		modes, mode;
47    DisplayModePtr	display_mode;
48    int			bpp = scrn->bitsPerPixel >> 3;
49    int			num;
50
51    num = 0;
52    display_mode = scrn->modes;
53    while (display_mode)
54    {
55	num++;
56	display_mode = display_mode->next;
57	if (display_mode == scrn->modes)
58	    break;
59    }
60
61    if (!num)
62	return FALSE;
63
64    modes = xalloc(num * sizeof(DGAModeRec));
65    if (!modes)
66	return FALSE;
67
68    num = 0;
69    display_mode = scrn->modes;
70    while (display_mode)
71    {
72	mode = modes + num++;
73
74	mode->mode = display_mode;
75	mode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
76        mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
77	if (display_mode->Flags & V_DBLSCAN)
78	    mode->flags |= DGA_DOUBLESCAN;
79	if (display_mode->Flags & V_INTERLACE)
80	    mode->flags |= DGA_INTERLACED;
81	mode->byteOrder = scrn->imageByteOrder;
82	mode->depth = scrn->depth;
83	mode->bitsPerPixel = scrn->bitsPerPixel;
84	mode->red_mask = scrn->mask.red;
85	mode->green_mask = scrn->mask.green;
86	mode->blue_mask = scrn->mask.blue;
87	mode->visualClass = (bpp == 1) ? PseudoColor : TrueColor;
88	mode->viewportWidth = display_mode->HDisplay;
89	mode->viewportHeight = display_mode->VDisplay;
90	mode->xViewportStep = (bpp == 3) ? 2 : 1;
91	mode->yViewportStep = 1;
92	mode->viewportFlags = DGA_FLIP_RETRACE;
93	mode->offset = 0;
94	mode->address = (unsigned char *) xf86_config->dga_address;
95	mode->bytesPerScanline = xf86_config->dga_stride;
96	mode->imageWidth = xf86_config->dga_width;
97	mode->imageHeight = xf86_config->dga_height;
98	mode->pixmapWidth = mode->imageWidth;
99	mode->pixmapHeight = mode->imageHeight;
100	mode->maxViewportX = mode->imageWidth -	mode->viewportWidth;
101	mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
102
103	display_mode = display_mode->next;
104	if (display_mode == scrn->modes)
105	    break;
106    }
107    if (xf86_config->dga_modes)
108	xfree (xf86_config->dga_modes);
109    xf86_config->dga_nmode = num;
110    xf86_config->dga_modes = modes;
111    return TRUE;
112}
113
114static Bool
115xf86_dga_set_mode(ScrnInfoPtr scrn, DGAModePtr display_mode)
116{
117    ScreenPtr		pScreen = scrn->pScreen;
118    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
119
120    if (!display_mode)
121    {
122	if (xf86_config->dga_save_mode)
123	{
124	    xf86SwitchMode(pScreen, xf86_config->dga_save_mode);
125	    xf86_config->dga_save_mode = NULL;
126	}
127    }
128    else
129    {
130	if (!xf86_config->dga_save_mode)
131	{
132	    xf86_config->dga_save_mode = scrn->currentMode;
133	    xf86SwitchMode(pScreen, display_mode->mode);
134	}
135    }
136    return TRUE;
137}
138
139static int
140xf86_dga_get_viewport(ScrnInfoPtr scrn)
141{
142    return 0;
143}
144
145static void
146xf86_dga_set_viewport(ScrnInfoPtr scrn, int x, int y, int flags)
147{
148   scrn->AdjustFrame(scrn->pScreen->myNum, x, y, flags);
149}
150
151static Bool
152xf86_dga_get_drawable_and_gc (ScrnInfoPtr scrn, DrawablePtr *ppDrawable, GCPtr *ppGC)
153{
154    ScreenPtr		pScreen = scrn->pScreen;
155    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
156    PixmapPtr		pPixmap;
157    GCPtr		pGC;
158
159    pPixmap = GetScratchPixmapHeader (pScreen, xf86_config->dga_width, xf86_config->dga_height,
160				      scrn->depth, scrn->bitsPerPixel, xf86_config->dga_stride,
161				      (char *) scrn->memPhysBase + scrn->fbOffset);
162    if (!pPixmap)
163	return FALSE;
164    pGC  = GetScratchGC (scrn->depth, pScreen);
165    if (!pGC)
166    {
167	FreeScratchPixmapHeader (pPixmap);
168	return FALSE;
169    }
170    *ppDrawable = &pPixmap->drawable;
171    *ppGC = pGC;
172    return TRUE;
173}
174
175static void
176xf86_dga_release_drawable_and_gc (ScrnInfoPtr scrn, DrawablePtr pDrawable, GCPtr pGC)
177{
178    FreeScratchGC (pGC);
179    FreeScratchPixmapHeader ((PixmapPtr) pDrawable);
180}
181
182static void
183xf86_dga_fill_rect(ScrnInfoPtr scrn, int x, int y, int w, int h, unsigned long color)
184{
185    GCPtr		pGC;
186    DrawablePtr		pDrawable;
187    XID			vals[1];
188    xRectangle		r;
189
190    if (!xf86_dga_get_drawable_and_gc (scrn, &pDrawable, &pGC))
191	return;
192    vals[0] = color;
193    ChangeGC (pGC, GCForeground, vals);
194    ValidateGC (pDrawable, pGC);
195    r.x = x;
196    r.y = y;
197    r.width = w;
198    r.height = h;
199    pGC->ops->PolyFillRect (pDrawable, pGC, 1, &r);
200    xf86_dga_release_drawable_and_gc (scrn, pDrawable, pGC);
201}
202
203static void
204xf86_dga_sync(ScrnInfoPtr scrn)
205{
206    ScreenPtr	pScreen = scrn->pScreen;
207    WindowPtr	pRoot = WindowTable [pScreen->myNum];
208    char	buffer[4];
209
210    pScreen->GetImage (&pRoot->drawable, 0, 0, 1, 1, ZPixmap, ~0L, buffer);
211}
212
213static void
214xf86_dga_blit_rect(ScrnInfoPtr scrn, int srcx, int srcy, int w, int h, int dstx, int dsty)
215{
216    DrawablePtr	pDrawable;
217    GCPtr	pGC;
218
219    if (!xf86_dga_get_drawable_and_gc (scrn, &pDrawable, &pGC))
220	return;
221    ValidateGC (pDrawable, pGC);
222    pGC->ops->CopyArea (pDrawable, pDrawable, pGC, srcx, srcy, w, h, dstx, dsty);
223    xf86_dga_release_drawable_and_gc (scrn, pDrawable, pGC);
224}
225
226static Bool
227xf86_dga_open_framebuffer(ScrnInfoPtr scrn,
228			  char **name,
229			  unsigned char **mem, int *size, int *offset, int *flags)
230{
231    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
232
233    *size = xf86_config->dga_stride * xf86_config->dga_height;
234    *mem = (unsigned char *) (xf86_config->dga_address);
235    *offset = 0;
236    *flags = DGA_NEED_ROOT;
237
238    return TRUE;
239}
240
241static void
242xf86_dga_close_framebuffer(ScrnInfoPtr scrn)
243{
244}
245
246static DGAFunctionRec xf86_dga_funcs = {
247   xf86_dga_open_framebuffer,
248   xf86_dga_close_framebuffer,
249   xf86_dga_set_mode,
250   xf86_dga_set_viewport,
251   xf86_dga_get_viewport,
252   xf86_dga_sync,
253   xf86_dga_fill_rect,
254   xf86_dga_blit_rect,
255   NULL
256};
257
258_X_EXPORT Bool
259xf86DiDGAReInit (ScreenPtr pScreen)
260{
261    ScrnInfoPtr		scrn = xf86Screens[pScreen->myNum];
262    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
263
264    if (!xf86_dga_get_modes (pScreen))
265	return FALSE;
266
267    return DGAReInitModes (pScreen, xf86_config->dga_modes, xf86_config->dga_nmode);
268}
269
270_X_EXPORT Bool
271xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address)
272{
273    ScrnInfoPtr		scrn = xf86Screens[pScreen->myNum];
274    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
275
276    xf86_config->dga_flags = 0;
277    xf86_config->dga_address = dga_address;
278    xf86_config->dga_width = scrn->virtualX;
279    xf86_config->dga_height = scrn->virtualY;
280    xf86_config->dga_stride = scrn->displayWidth * scrn->bitsPerPixel >> 3;
281
282    if (!xf86_dga_get_modes (pScreen))
283	return FALSE;
284
285    return DGAInit(pScreen, &xf86_dga_funcs, xf86_config->dga_modes, xf86_config->dga_nmode);
286}
287