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