1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_video.c,v 1.7tsi Exp $ */ 2/* 3 * $Workfile: nsc_gx1_video.c $ 4 * $Revision: 1.1.1.1 $ 5 * $Author: mrg $ 6 * 7 * File Contents: This file consists of main Xfree video supported routines. 8 * 9 * Project: Geode Xfree Frame buffer device driver. 10 * 11 */ 12 13/* 14 * NSC_LIC_ALTERNATIVE_PREAMBLE 15 * 16 * Revision 1.0 17 * 18 * National Semiconductor Alternative GPL-BSD License 19 * 20 * National Semiconductor Corporation licenses this software 21 * ("Software"): 22 * 23 * National Xfree frame buffer driver 24 * 25 * under one of the two following licenses, depending on how the 26 * Software is received by the Licensee. 27 * 28 * If this Software is received as part of the Linux Framebuffer or 29 * other GPL licensed software, then the GPL license designated 30 * NSC_LIC_GPL applies to this Software; in all other circumstances 31 * then the BSD-style license designated NSC_LIC_BSD shall apply. 32 * 33 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 34 35/* NSC_LIC_BSD 36 * 37 * National Semiconductor Corporation Open Source License for 38 * 39 * National Xfree frame buffer driver 40 * 41 * (BSD License with Export Notice) 42 * 43 * Copyright (c) 1999-2001 44 * National Semiconductor Corporation. 45 * All rights reserved. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 51 * * Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 54 * * Redistributions in binary form must reproduce the above 55 * copyright notice, this list of conditions and the following 56 * disclaimer in the documentation and/or other materials provided 57 * with the distribution. 58 * 59 * * Neither the name of the National Semiconductor Corporation nor 60 * the names of its contributors may be used to endorse or promote 61 * products derived from this software without specific prior 62 * written permission. 63 * 64 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 65 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 66 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 67 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 68 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 69 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 70 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 71 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 72 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 73 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 74 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 75 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 76 * OF SUCH DAMAGE. 77 * 78 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 79 * YOUR JURISDICTION. It is licensee's responsibility to comply with 80 * any export regulations applicable in licensee's jurisdiction. Under 81 * CURRENT (2001) U.S. export regulations this software 82 * is eligible for export from the U.S. and can be downloaded by or 83 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 84 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 85 * Syria, Sudan, Afghanistan and any other country to which the U.S. 86 * has embargoed goods and services. 87 * 88 * END_NSC_LIC_BSD */ 89 90/* NSC_LIC_GPL 91 * 92 * National Semiconductor Corporation Gnu General Public License for 93 * 94 * National Xfree frame buffer driver 95 * 96 * (GPL License with Export Notice) 97 * 98 * Copyright (c) 1999-2001 99 * National Semiconductor Corporation. 100 * All rights reserved. 101 * 102 * Redistribution and use in source and binary forms, with or without 103 * modification, are permitted under the terms of the GNU General 104 * Public License as published by the Free Software Foundation; either 105 * version 2 of the License, or (at your option) any later version 106 * 107 * In addition to the terms of the GNU General Public License, neither 108 * the name of the National Semiconductor Corporation nor the names of 109 * its contributors may be used to endorse or promote products derived 110 * from this software without specific prior written permission. 111 * 112 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 113 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 114 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 115 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 116 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 117 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 118 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 119 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 120 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 121 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 122 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 123 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 124 * OF SUCH DAMAGE. See the GNU General Public License for more details. 125 * 126 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 127 * YOUR JURISDICTION. It is licensee's responsibility to comply with 128 * any export regulations applicable in licensee's jurisdiction. Under 129 * CURRENT (2001) U.S. export regulations this software 130 * is eligible for export from the U.S. and can be downloaded by or 131 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 132 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 133 * Syria, Sudan, Afghanistan and any other country to which the U.S. 134 * has embargoed goods and services. 135 * 136 * You should have received a copy of the GNU General Public License 137 * along with this file; if not, write to the Free Software Foundation, 138 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 139 * 140 * END_NSC_LIC_GPL */ 141 142/* 143 * Fixes & Extensions to support Y800 greyscale modes 144 * Alan Hourihane <alanh@fairlite.demon.co.uk> 145 */ 146 147#ifdef HAVE_CONFIG_H 148#include "config.h" 149#endif 150 151#include "xf86.h" 152#include "xf86_OSproc.h" 153#include "xf86Resources.h" 154#include "compiler.h" 155#include "xf86PciInfo.h" 156#include "xf86Pci.h" 157#include "xf86fbman.h" 158#include "regionstr.h" 159 160#include "nsc.h" 161#include <X11/extensions/Xv.h> 162#include "xaa.h" 163#include "xaalocal.h" 164#include "dixstruct.h" 165#include "fourcc.h" 166#include "nsc_fourcc.h" 167 168#define OFF_DELAY 200 /* milliseconds */ 169#define FREE_DELAY 60000 170 171#define OFF_TIMER 0x01 172#define FREE_TIMER 0x02 173#define CLIENT_VIDEO_ON 0x04 174 175#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 176#define XV_PROFILE 0 177#define REINIT 1 178 179void GX1InitVideo(ScreenPtr pScreen); 180void GX1ResetVideo(ScrnInfoPtr pScrn); 181 182#define DBUF 0 183 184static XF86VideoAdaptorPtr GX1SetupImageVideo(ScreenPtr); 185static void GX1InitOffscreenImages(ScreenPtr); 186static void GX1StopVideo(ScrnInfoPtr, pointer, Bool); 187static int GX1SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 188static int GX1GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); 189static void GX1QueryBestSize(ScrnInfoPtr, Bool, 190 short, short, short, short, unsigned int *, 191 unsigned int *, pointer); 192static int GX1PutImage(ScrnInfoPtr, 193 short, short, short, short, short, short, 194 short, short, int, unsigned char *, short, short, 195 Bool, RegionPtr, pointer, DrawablePtr); 196static int GX1QueryImageAttributes(ScrnInfoPtr, 197 int, unsigned short *, unsigned short *, 198 int *, int *); 199 200static void GX1BlockHandler(int, pointer, pointer, pointer); 201 202void GX1SetVideoPosition(int, int, int, int, 203 short, short, short, short, int, int, ScrnInfoPtr); 204 205extern void GX1AccelSync(ScrnInfoPtr pScreenInfo); 206 207#if !defined(STB_X) 208extern int DeltaX, DeltaY; 209#else 210int DeltaX, DeltaY; 211#endif 212 213#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 214 215static Atom xvColorKey, xvColorKeyMode, xvFilter 216#if DBUF 217 , xvDoubleBuffer 218#endif 219 ; 220 221/*---------------------------------------------------------------------------- 222 * GX1InitVideo 223 * 224 * Description :This is the initialization routine.It creates a new video adapter 225 * and calls GX1SetupImageVideo to initialize the adaptor by filling 226 * XF86VideoAdaptorREc.Then it lists the existing adaptors and adds the 227 * new one to it. Finally the list of XF86VideoAdaptorPtr pointers are 228 * passed to the xf86XVScreenInit(). 229 * 230 * Parameters. 231 * ScreenPtr 232 * pScreen :Screen handler pointer having screen information. 233 * 234 * Returns :none 235 * 236 * Comments :none 237 * 238*---------------------------------------------------------------------------- 239*/ 240void 241GX1InitVideo(ScreenPtr pScreen) 242{ 243 GeodePtr pGeode; 244 245 ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; 246 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 247 XF86VideoAdaptorPtr newAdaptor = NULL; 248 249 int num_adaptors; 250 251 pGeode = GEODEPTR(pScreenInfo); 252 253 254 DEBUGMSG(0, (0, X_NONE, "InitVideo\n")); 255 newAdaptor = GX1SetupImageVideo(pScreen); 256 GX1InitOffscreenImages(pScreen); 257 258 num_adaptors = xf86XVListGenericAdaptors(pScreenInfo, &adaptors); 259 260 if (newAdaptor) { 261 if (!num_adaptors) { 262 num_adaptors = 1; 263 adaptors = &newAdaptor; 264 } else { 265 newAdaptors = /* need to free this someplace */ 266 xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); 267 if (newAdaptors) { 268 memcpy(newAdaptors, adaptors, num_adaptors * 269 sizeof(XF86VideoAdaptorPtr)); 270 newAdaptors[num_adaptors] = newAdaptor; 271 adaptors = newAdaptors; 272 num_adaptors++; 273 } 274 } 275 } 276 277 if (num_adaptors) 278 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 279 280 if (newAdaptors) 281 xfree(newAdaptors); 282} 283 284/* client libraries expect an encoding */ 285static XF86VideoEncodingRec DummyEncoding[1] = { 286 { 287 0, 288 "XV_IMAGE", 289 1024, 1024, 290 {1, 1} 291 } 292}; 293 294#define NUM_FORMATS 4 295 296static XF86VideoFormatRec Formats[NUM_FORMATS] = { 297 {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 298}; 299 300#if DBUF 301#define NUM_ATTRIBUTES 4 302#else 303#define NUM_ATTRIBUTES 3 304#endif 305 306static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { 307#if DBUF 308 {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 309#endif 310 {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 311 {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, 312 {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} 313}; 314 315#define NUM_IMAGES 7 316 317static XF86ImageRec Images[NUM_IMAGES] = { 318 XVIMAGE_UYVY, 319 XVIMAGE_YUY2, 320 XVIMAGE_Y2YU, 321 XVIMAGE_YVYU, 322 XVIMAGE_Y800, 323 XVIMAGE_I420, 324 XVIMAGE_YV12 325}; 326 327typedef struct 328{ 329 FBAreaPtr area; 330 FBLinearPtr linear; 331 RegionRec clip; 332 CARD32 colorKey; 333 CARD32 colorKeyMode; 334 CARD32 filter; 335 CARD32 videoStatus; 336 Time offTime; 337 Time freeTime; 338#if DBUF 339 Bool doubleBuffer; 340 int currentBuffer; 341#endif 342} 343GeodePortPrivRec, *GeodePortPrivPtr; 344 345#define GET_PORT_PRIVATE(pScrn) \ 346 (GeodePortPrivPtr)((GEODEPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 347 348/*---------------------------------------------------------------------------- 349 * GX1SetColorKey 350 * 351 * Description :This function reads the color key for the pallete and 352 * sets the video color key register. 353 * 354 * Parameters. 355 * ScreenInfoPtr 356 * pScrn :Screen pointer having screen information. 357 * pPriv :Video port private data 358 * 359 * Returns :none 360 * 361 * Comments :none 362 * 363*---------------------------------------------------------------------------- 364*/ 365static INT32 366GX1SetColorkey(ScrnInfoPtr pScrn, GeodePortPrivPtr pPriv) 367{ 368 int red, green, blue; 369 unsigned long key; 370 371 DEBUGMSG(0, (0, X_NONE, "ColorKey\n")); 372 switch (pScrn->depth) { 373 case 8: 374 GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key)); 375 red = ((key >> 16) & 0xFF); 376 green = ((key >> 8) & 0xFF); 377 blue = (key & 0xFF); 378 break; 379 default: 380 red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red << (8 - 381 pScrn-> 382 weight. 383 red); 384 green = 385 (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset. 386 green << (8 - pScrn->weight.green); 387 blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset. 388 blue << (8 - pScrn->weight.blue); 389 break; 390 } 391 GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFCFCFC, 392 (pPriv->colorKeyMode == 0))); 393 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 394 return 0; 395} 396 397/*---------------------------------------------------------------------------- 398 * GX1ResetVideo 399 * 400 * Description : This function resets the video 401 * 402 * Parameters. 403 * ScreenInfoPtr 404 * pScrn :Screen pointer having screen information. 405 * 406 * Returns :None 407 * 408 * Comments :none 409 * 410*---------------------------------------------------------------------------- 411*/ 412 413void 414GX1ResetVideo(ScrnInfoPtr pScrn) 415{ 416 GeodePtr pGeode = GEODEPTR(pScrn); 417 418 GeodePortPrivPtr pPriv = pGeode->adaptor->pPortPrivates[0].ptr; 419 420 DEBUGMSG(0, (0, X_NONE, "ResetVideo\n")); 421 if (!pGeode->NoAccel) GX1AccelSync(pScrn); 422 GFX(set_video_palette(NULL)); 423 GX1SetColorkey(pScrn, pPriv); 424 GFX(set_video_filter(pPriv->filter, pPriv->filter)); 425} 426 427/*---------------------------------------------------------------------------- 428 * GX1SetupImageVideo 429 * 430 * Description : This function allocates space for a Videoadaptor and initializes 431 * the XF86VideoAdaptorPtr record. 432 * 433 * Parameters. 434 * ScreenPtr 435 * pScreen :Screen handler pointer having screen information. 436 * 437 * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record. 438 * 439 * Comments :none 440 * 441*---------------------------------------------------------------------------- 442*/ 443 444static XF86VideoAdaptorPtr 445GX1SetupImageVideo(ScreenPtr pScreen) 446{ 447 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 448 GeodePtr pGeode = GEODEPTR(pScrn); 449 XF86VideoAdaptorPtr adapt; 450 GeodePortPrivPtr pPriv; 451 452 DEBUGMSG(0, (0, X_NONE, "SetupImageVideo\n")); 453 if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + 454 sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) 455 return NULL; 456 457 adapt->type = XvWindowMask | XvInputMask | XvImageMask; 458 adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 459 adapt->name = "National Semiconductor Corporation"; 460 adapt->nEncodings = 1; 461 adapt->pEncodings = DummyEncoding; 462 adapt->nFormats = NUM_FORMATS; 463 adapt->pFormats = Formats; 464 adapt->nPorts = 1; 465 adapt->pPortPrivates = (DevUnion *) (&adapt[1]); 466 pPriv = (GeodePortPrivPtr) (&adapt->pPortPrivates[1]); 467 adapt->pPortPrivates[0].ptr = (pointer) (pPriv); 468 adapt->pAttributes = Attributes; 469 adapt->nImages = NUM_IMAGES; 470 adapt->nAttributes = NUM_ATTRIBUTES; 471 adapt->pImages = Images; 472 adapt->PutVideo = NULL; 473 adapt->PutStill = NULL; 474 adapt->GetVideo = NULL; 475 adapt->GetStill = NULL; 476 adapt->StopVideo = GX1StopVideo; 477 adapt->SetPortAttribute = GX1SetPortAttribute; 478 adapt->GetPortAttribute = GX1GetPortAttribute; 479 adapt->QueryBestSize = GX1QueryBestSize; 480 adapt->PutImage = GX1PutImage; 481 adapt->QueryImageAttributes = GX1QueryImageAttributes; 482 483 pPriv->colorKey = pGeode->videoKey; 484 pPriv->colorKeyMode = 0; 485 pPriv->filter = 0; 486 pPriv->videoStatus = 0; 487#if DBUF 488 pPriv->doubleBuffer = TRUE; 489 pPriv->currentBuffer = 0; /* init to first buffer */ 490#endif 491 492 /* gotta uninit this someplace */ 493 REGION_NULL(pScreen, &pPriv->clip); 494 495 pGeode->adaptor = adapt; 496 497 pGeode->BlockHandler = pScreen->BlockHandler; 498 pScreen->BlockHandler = GX1BlockHandler; 499 500 xvColorKey = MAKE_ATOM("XV_COLORKEY"); 501 xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); 502 xvFilter = MAKE_ATOM("XV_FILTER"); 503#if DBUF 504 xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 505#endif 506 507 GX1ResetVideo(pScrn); 508 509 return adapt; 510} 511 512/*---------------------------------------------------------------------------- 513 * GX1StopVideo 514 * 515 * Description :This function is used to stop input and output video 516 * 517 * Parameters. 518 * pScreenInfo 519 * pScrn :Screen handler pointer having screen information. 520 * data :Pointer to the video port's private data 521 * exit :Flag indicating whether the offscreen areas used for video 522 * to be deallocated or not. 523 * Returns :none 524 * 525 * Comments :none 526 * 527*---------------------------------------------------------------------------- 528*/ 529static void 530GX1StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) 531{ 532 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 533 GeodePtr pGeode = GEODEPTR(pScrn); 534 535 DEBUGMSG(0, (0, X_NONE, "StopVideo\n")); 536 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 537 538 if (!pGeode->NoAccel) GX1AccelSync(pScrn); 539 if (exit) { 540 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 541 GFX(set_video_enable(0)); 542 } 543 if (pPriv->area) { 544 xf86FreeOffscreenArea(pPriv->area); 545 pPriv->area = NULL; 546 } 547 pPriv->videoStatus = 0; 548 pGeode->OverlayON = FALSE; 549 } else { 550 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 551 pPriv->videoStatus |= OFF_TIMER; 552 pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 553 } 554 } 555} 556 557/*---------------------------------------------------------------------------- 558 * GX1SetPortAttribute 559 * 560 * Description :This function is used to set the attributes of a port like colorkeymode, 561 * double buffer support and filter. 562 * 563 * Parameters. 564 * pScreenInfo 565 * Ptr :Screen handler pointer having screen information. 566 * data :Pointer to the video port's private data 567 * attribute :The port attribute to be set 568 * value :Value of the attribute to be set. 569 * 570 * Returns :Sucess if the attribute is supported, else BadMatch 571 * 572 * Comments :none 573 * 574*---------------------------------------------------------------------------- 575*/ 576static int 577GX1SetPortAttribute(ScrnInfoPtr pScrn, 578 Atom attribute, INT32 value, pointer data) 579{ 580 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 581 GeodePtr pGeode = GEODEPTR(pScrn); 582 583 if (!pGeode->NoAccel) GX1AccelSync(pScrn); 584 if (attribute == xvColorKey) { 585 pPriv->colorKey = value; 586 GX1SetColorkey(pScrn, pPriv); 587 } 588#if DBUF 589 else if (attribute == xvDoubleBuffer) { 590 if ((value < 0) || (value > 1)) 591 return BadValue; 592 pPriv->doubleBuffer = value; 593 } 594#endif 595 else if (attribute == xvColorKeyMode) { 596 pPriv->colorKeyMode = value; 597 GX1SetColorkey(pScrn, pPriv); 598 } else if (attribute == xvFilter) { 599 pPriv->filter = value; 600 GFX(set_video_filter(pPriv->filter, pPriv->filter)); 601 } else 602 return BadMatch; 603 604 return Success; 605} 606 607/*---------------------------------------------------------------------------- 608 * GX1GetPortAttribute 609 * 610 * Description :This function is used to get the attributes of a port like hue, 611 * saturation,brightness or contrast. 612 * 613 * Parameters. 614 * pScreenInfo 615 * Ptr :Screen handler pointer having screen information. 616 * data :Pointer to the video port's private data 617 * attribute :The port attribute to be read 618 * value :Pointer to the value of the attribute to be read. 619 * 620 * Returns :Sucess if the attribute is supported, else BadMatch 621 * 622 * Comments :none 623 * 624*---------------------------------------------------------------------------- 625*/ 626static int 627GX1GetPortAttribute(ScrnInfoPtr pScrn, 628 Atom attribute, INT32 * value, pointer data) 629{ 630 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 631 632 if (attribute == xvColorKey) { 633 *value = pPriv->colorKey; 634 } 635#if DBUF 636 else if (attribute == xvDoubleBuffer) { 637 *value = (pPriv->doubleBuffer) ? 1 : 0; 638 } 639#endif 640 else if (attribute == xvColorKeyMode) { 641 *value = pPriv->colorKeyMode; 642 } else if (attribute == xvFilter) { 643 *value = pPriv->filter; 644 } else 645 return BadMatch; 646 647 return Success; 648} 649 650/*---------------------------------------------------------------------------- 651 * GX1QueryBestSize 652 * 653 * Description :This function provides a way to query what the destination dimensions 654 * would end up being if they were to request that an area vid_w by vid_h 655 * from the video stream be scaled to rectangle of drw_w by drw_h on 656 * the screen. 657 * 658 * Parameters. 659 * ScreenInfoPtr 660 * pScrn :Screen handler pointer having screen information. 661 * data :Pointer to the video port's private data 662 * vid_w,vid_h :Width and height of the video data. 663 * drw_w,drw_h :Width and height of the scaled rectangle. 664 * p_w,p_h :Width and height of the destination rectangle. 665 * 666 * Returns :None 667 * 668 * Comments :None 669 * 670*---------------------------------------------------------------------------- 671*/ 672static void 673GX1QueryBestSize(ScrnInfoPtr pScrn, 674 Bool motion, 675 short vid_w, short vid_h, 676 short drw_w, short drw_h, 677 unsigned int *p_w, unsigned int *p_h, pointer data) 678{ 679 DEBUGMSG(0, (0, X_NONE, "QueryBestSize\n")); 680 *p_w = drw_w; 681 *p_h = drw_h; 682 683 if (*p_w > 16384) 684 *p_w = 16384; 685} 686static void 687GX1CopyGreyscale(unsigned char *src, 688 unsigned char *dst, int srcPitch, int dstPitch, int h, int w) 689{ 690 int i; 691 unsigned char *src2 = src; 692 unsigned char *dst2 = dst; 693 unsigned char *dst3; 694 unsigned char *src3; 695 696 dstPitch <<= 1; 697 698 while (h--) { 699 dst3 = dst2; 700 src3 = src2; 701 for (i = 0; i < w; i++) { 702 *dst3++ = *src3++; /* Copy Y data */ 703 *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ 704 } 705 src3 = src2; 706 for (i = 0; i < w; i++) { 707 *dst3++ = *src3++; /* Copy Y data */ 708 *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ 709 } 710 dst2 += dstPitch; 711 src2 += srcPitch; 712 } 713} 714 715/*---------------------------------------------------------------------------- 716 * GX1CopyData 717 * 718 * Description : Copies data from src to destination 719 * 720 * Parameters. 721 * src : pointer to the source data 722 * dst : pointer to destination data 723 * srcPitch : pitch of the srcdata 724 * dstPitch : pitch of the destination data 725 * h & w : height and width of source data 726 * 727 * Returns :None 728 * 729 * Comments :None 730 * 731*---------------------------------------------------------------------------- 732*/ 733 734static void 735GX1CopyData(unsigned char *src, unsigned char *dst, 736 int srcPitch, int dstPitch, int h, int w) 737{ 738 w <<= 1; 739 while (h--) { 740 memcpy(dst, src, w); 741 src += srcPitch; 742 dst += dstPitch; 743 } 744} 745 746static void 747GX1CopyMungedData(unsigned char *src1, 748 unsigned char *src2, 749 unsigned char *src3, 750 unsigned char *dst1, 751 int srcPitch, int srcPitch2, int dstPitch, int h, int w) 752{ 753 CARD32 *dstCur = (CARD32 *) dst1; 754 CARD32 *dstNext = (CARD32 *) dst1; 755 int i, j, k, m, n; 756 CARD32 crcb; 757 758#if XV_PROFILE 759 long oldtime, newtime; 760#endif 761 762 DEBUGMSG(0, (0, X_NONE, "CopyMungedData\n")); 763 /* dstPitch is in byte count, but we write longs. 764 * so divide dstpitch by 4 765 */ 766 dstPitch >>= 2; 767 /* Width is in byte but video data is 16bit 768 */ 769 w >>= 1; 770 /* We render 2 scanlines at one shot, handle the odd count */ 771 m = h & 1; 772 /* decrement the height since we write 2 scans */ 773 h -= 1; 774 /* we traverse by 2 bytes in src Y */ 775 srcPitch <<= 1; 776#if XV_PROFILE 777 UpdateCurrentTime(); 778 oldtime = currentTime.milliseconds; 779#endif 780 781 for (j = 0; j < h; j += 2) { 782 /* calc the next dest scan start */ 783 dstNext = dstCur + dstPitch; 784 for (i = 0; i < w; i++) { 785 /* crcb is same for the x pixel for 2 scans */ 786 crcb = (src3[i] << 8) | (src2[i] << 24); 787 788 n = i << 1; 789 790 /* write the first scan pixel DWORD */ 791 dstCur[i] = src1[n] | (src1[n + 1] << 16) | crcb; 792 793 /* calc the offset of next pixel */ 794 k = n + srcPitch; 795 796 /* write the 2nd scan pixel DWORD */ 797 dstNext[i] = src1[k] | (src1[k + 1] << 16) | crcb; 798 } 799 /* increment the offsets */ 800 801 /* Y */ 802 src1 += srcPitch; 803 /* crcb */ 804 src2 += srcPitch2; 805 src3 += srcPitch2; 806 /* processed dest */ 807 dstCur += (dstPitch << 1); 808 } 809 810 /* if any scans remaining */ 811 if (m) { 812 for (i = 0, k = 0; i < w; i++, k += 2) { 813 dstCur[i] = src1[k] | (src1[k + 1] << 16) | 814 (src3[i] << 8) | (src2[i] << 24); 815 } 816 } 817#if XV_PROFILE 818 UpdateCurrentTime(); 819 newtime = currentTime.milliseconds; 820 DEBUGMSG(1, (0, X_NONE, "CMD %d\n", newtime - oldtime)); 821#endif 822} 823 824static FBAreaPtr 825GX1AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int numlines) 826{ 827 ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; 828 FBAreaPtr new_area; 829 830 if (area) { 831 if ((area->box.y2 - area->box.y1) >= numlines) 832 return area; 833 834 if (xf86ResizeOffscreenArea(area, pScrn->displayWidth, numlines)) 835 return area; 836 837 xf86FreeOffscreenArea(area); 838 } 839 840 new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, 841 numlines, 0, NULL, NULL, NULL); 842 843 if (!new_area) { 844 int max_w, max_h; 845 846 xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, 847 FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); 848 849 if ((max_w < pScrn->displayWidth) || (max_h < numlines)) 850 return NULL; 851 852 xf86PurgeUnlockedOffscreenAreas(pScreen); 853 new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, 854 numlines, 0, NULL, NULL, NULL); 855 } 856 return new_area; 857} 858 859static BoxRec dstBox; 860static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0; 861static INT32 Bx1, Bx2, By1, By2; 862static int top, left, npixels, nlines; 863static int offset, s1offset = 0, s2offset = 0, s3offset = 0; 864static unsigned char *dst_start; 865static int TVOverScanX; 866 867static Bool 868RegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult) 869{ 870 pRclResult->x1 = max(pRcl1->x1, pRcl2->x1); 871 pRclResult->x2 = min(pRcl1->x2, pRcl2->x2); 872 873 if (pRclResult->x1 <= pRclResult->x2) { 874 pRclResult->y1 = max(pRcl1->y1, pRcl2->y1); 875 pRclResult->y2 = min(pRcl1->y2, pRcl2->y2); 876 877 if (pRclResult->y1 <= pRclResult->y2) { 878 return (TRUE); 879 } 880 } 881 882 return (FALSE); 883} 884 885void 886GX1SetVideoPosition(int x, int y, int width, int height, 887 short src_w, short src_h, short drw_w, short drw_h, 888 int id, int offset, ScrnInfoPtr pScrn) 889{ 890 GeodePtr pGeode = GEODEPTR(pScrn); 891 long xstart, ystart, xend, yend; 892 unsigned long lines = 0; 893 unsigned long y_extra = 0; 894 unsigned short crop = 0; 895 BoxRec ovly, display, result; 896 897#if defined(STB_X) 898 unsigned long startAddress = 0; 899#endif 900 xend = x + drw_w; 901 yend = y + drw_h; 902 903 /* Take care of panning when panel is present */ 904 905#if defined(STB_X) 906 Gal_get_display_offset(&startAddress); 907 DeltaY = startAddress / pGeode->Pitch; 908 DeltaX = startAddress & (pGeode->Pitch - 1); 909 DeltaX /= (pScrn->bitsPerPixel >> 3); 910#endif 911 912 if (pGeode->Panel) { 913 ovly.x1 = x; 914 ovly.x2 = x + pGeode->video_dstw; 915 ovly.y1 = y; 916 ovly.y2 = y + pGeode->video_dsth; 917 918 display.x1 = DeltaX; 919 display.x2 = DeltaX + pGeode->FPBX; 920 display.y1 = DeltaY; 921 display.y2 = DeltaY + pGeode->FPBY; 922 923 x = xend = 0; 924 925 if (RegionsIntersect(&display, &ovly, &result)) { 926 x = ovly.x1 - DeltaX; 927 xend = ovly.x2 - DeltaX; 928 y = ovly.y1 - DeltaY; 929 yend = ovly.y2 - DeltaY; 930 } 931 } 932 933 /* LEFT CLIPPING */ 934 935 if (x < 0) { 936 if (TVOverScanX) 937 xstart = TVOverScanX; 938 else 939 xstart = 0; 940 } else { 941 if (TVOverScanX) 942 xstart = TVOverScanX; 943 else 944 xstart = (unsigned long)x; 945 } 946 drw_w -= (xstart - x); 947 948 /* TOP CLIPPING */ 949 950 if (y < 0) { 951 lines = (-y) * src_h / drw_h; 952 ystart = 0; 953 drw_h += y; 954 y_extra = lines * dstPitch; 955 } else { 956 ystart = y; 957 lines = 0; 958 y_extra = 0; 959 } 960 961 /* CLIP RIGHT AND BOTTOM FOR TV OVER SCAN */ 962 if (pGeode->TV_Overscan_On) { 963 crop = (pGeode->TVOw + pGeode->TVOx); 964 if ((xstart + drw_w) > crop) 965 xend = crop; 966 crop = (pGeode->TVOh + pGeode->TVOy); 967 if ((ystart + drw_h) > crop) 968 yend = crop; 969 } 970 GFX(set_video_window(xstart, ystart, xend - xstart, yend - ystart)); 971 GFX(set_video_offset(offset + y_extra)); 972 GFX(set_video_left_crop(xstart - x)); 973 974} 975 976/*---------------------------------------------------------------------------- 977 * GX1DisplayVideo 978 * 979 * Description : This function sets up the video registers for playing video 980 * It sets up the video format,width, height & position of the 981 * video window ,video offsets( y,u,v) and video pitches(y,u,v) 982 * Parameters. 983 * 984 * Returns :None 985 * 986 * Comments :None 987 * 988*---------------------------------------------------------------------------- 989*/ 990 991static void 992GX1DisplayVideo(ScrnInfoPtr pScrn, 993 int id, 994 int offset, 995 short width, short height, 996 int pitch, 997 int x1, int y1, int x2, int y2, 998 BoxPtr dstBox, 999 short src_w, short src_h, short drw_w, short drw_h) 1000{ 1001 GeodePtr pGeode = GEODEPTR(pScrn); 1002 1003 /* DisplayModePtr mode = pScrn->currentMode; */ 1004 if (!pGeode->NoAccel) GX1AccelSync(pScrn); 1005 1006 GFX(set_video_enable(1)); 1007 1008 switch (id) { 1009 case FOURCC_UYVY: /* UYVY */ 1010 GFX(set_video_format(VIDEO_FORMAT_UYVY)); 1011 break; 1012 case FOURCC_Y800: /* Y800 - greyscale - we munge it! */ 1013 case FOURCC_YV12: 1014 case FOURCC_I420: 1015 case FOURCC_YUY2: /* YUY2 */ 1016 GFX(set_video_format(VIDEO_FORMAT_YUYV)); 1017 break; 1018 case FOURCC_Y2YU: /* Y2YU */ 1019 GFX(set_video_format(VIDEO_FORMAT_Y2YU)); 1020 break; 1021 case FOURCC_YVYU: /* YVYU */ 1022 GFX(set_video_format(VIDEO_FORMAT_YVYU)); 1023 break; 1024 } 1025 1026 if (pGeode->TV_Overscan_On) { 1027 if (dstBox->x1 < 0) 1028 TVOverScanX = pGeode->TVOx; 1029 else 1030 TVOverScanX = 0; 1031 dstBox->x1 += pGeode->TVOx; 1032 dstBox->y1 += pGeode->TVOy; 1033 } 1034 if (pGeode->Panel) { 1035 pGeode->video_x = dstBox->x1; 1036 pGeode->video_y = dstBox->y1; 1037 pGeode->video_w = width; 1038 pGeode->video_h = height; 1039 pGeode->video_srcw = src_w; 1040 pGeode->video_srch = src_h; 1041 pGeode->video_dstw = drw_w; 1042 pGeode->video_dsth = drw_h; 1043 pGeode->video_offset = offset; 1044 pGeode->video_id = id; 1045 pGeode->video_scrnptr = pScrn; 1046 } 1047 1048 GFX(set_video_size(width, height)); 1049 GFX(set_video_scale(width, height, drw_w, drw_h)); 1050 GX1SetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, src_h, 1051 drw_w, drw_h, id, offset, pScrn); 1052 GFX(set_color_space_YUV(0)); 1053} 1054 1055/*---------------------------------------------------------------------------- 1056 * GX1PutImage : This function writes a single frame of video into a drawable. 1057 * The position and size of the source rectangle is specified by src_x,src_y, 1058 * src_w and src_h. This data is stored in a system memory buffer at buf. 1059 * The position and size of the destination rectangle is specified by drw_x, 1060 * drw_y,drw_w,drw_h.The data is in the format indicated by the image descriptor 1061 * and represents a source of size width by height. If sync is TRUE the driver 1062 * should not return from this function until it is through reading the data from 1063 * buf. Returning when sync is TRUE indicates that it is safe for the data at buf 1064 * to be replaced,freed, or modified. 1065 * 1066 * 1067 * Description : 1068 * Parameters. 1069 * 1070 * Returns :None 1071 * 1072 * Comments :None 1073 * 1074*---------------------------------------------------------------------------- 1075*/ 1076 1077static int 1078GX1PutImage(ScrnInfoPtr pScrn, 1079 short src_x, short src_y, 1080 short drw_x, short drw_y, 1081 short src_w, short src_h, 1082 short drw_w, short drw_h, 1083 int id, unsigned char *buf, 1084 short width, short height, 1085 Bool sync, RegionPtr clipBoxes, pointer data, 1086 DrawablePtr pDraw) 1087{ 1088 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 1089 GeodePtr pGeode = GEODEPTR(pScrn); 1090 int pitch, new_h; 1091 1092#if REINIT 1093 BOOL ReInitVideo = FALSE; 1094#endif 1095 1096#if XV_PROFILE 1097 long oldtime, newtime; 1098 1099 UpdateCurrentTime(); 1100 oldtime = currentTime.milliseconds; 1101#endif 1102 1103#if REINIT 1104/* update cliplist */ 1105 if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 1106 ReInitVideo = TRUE; 1107 } 1108 if (ReInitVideo) { 1109 DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n")); 1110#endif 1111 1112 if (drw_w > 16384) 1113 drw_w = 16384; 1114 1115 /* Clip */ 1116 Bx1 = src_x; 1117 Bx2 = src_x + src_w; 1118 By1 = src_y; 1119 By2 = src_y + src_h; 1120 1121 if ((Bx1 >= Bx2) || (By1 >= By2)) 1122 return Success; 1123 1124 dstBox.x1 = drw_x; 1125 dstBox.x2 = drw_x + drw_w; 1126 dstBox.y1 = drw_y; 1127 dstBox.y2 = drw_y + drw_h; 1128 1129 dstBox.x1 -= pScrn->frameX0; 1130 dstBox.x2 -= pScrn->frameX0; 1131 dstBox.y1 -= pScrn->frameY0; 1132 dstBox.y2 -= pScrn->frameY0; 1133 1134 pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; 1135 1136 dstPitch = ((width << 1) + 3) & ~3; 1137 1138 switch (id) { 1139 case FOURCC_YV12: 1140 case FOURCC_I420: 1141 srcPitch = (width + 3) & ~3; /* of luma */ 1142 s2offset = srcPitch * height; 1143 srcPitch2 = ((width >> 1) + 3) & ~3; 1144 s3offset = (srcPitch2 * (height >> 1)) + s2offset; 1145 break; 1146 case FOURCC_UYVY: 1147 case FOURCC_YUY2: 1148 case FOURCC_Y800: 1149 default: 1150 srcPitch = (width << 1); 1151 break; 1152 } 1153 1154 /* Find how many pitch scanlines required to store the data */ 1155 new_h = ((dstPitch * height) + pitch - 1) / pitch; 1156 1157#if DBUF 1158 if (pPriv->doubleBuffer) 1159 new_h <<= 1; 1160#endif 1161 1162 if (!(pPriv->area = GX1AllocateMemory(pScrn, pPriv->area, new_h))) 1163 return BadAlloc; 1164 1165 /* copy data */ 1166 top = By1; 1167 left = Bx1 & ~1; 1168 npixels = ((Bx2 + 1) & ~1) - left; 1169 1170 switch (id) { 1171 case FOURCC_YV12: 1172 case FOURCC_I420: 1173 { 1174 int tmp; 1175 1176 top &= ~1; 1177 offset = (pPriv->area->box.y1 * pitch) + (top * dstPitch); 1178 1179#if DBUF 1180 if (pPriv->doubleBuffer && pPriv->currentBuffer) 1181 offset += (new_h >> 1) * pitch; 1182#endif 1183 1184 dst_start = pGeode->FBBase + offset + left; 1185 tmp = ((top >> 1) * srcPitch2) + (left >> 1); 1186 s2offset += tmp; 1187 s3offset += tmp; 1188 if (id == FOURCC_I420) { 1189 tmp = s2offset; 1190 s2offset = s3offset; 1191 s3offset = tmp; 1192 } 1193 nlines = ((By2 + 1) & ~1) - top; 1194 } 1195 break; 1196 1197 case FOURCC_UYVY: 1198 case FOURCC_YUY2: 1199 case FOURCC_Y800: 1200 default: 1201 left <<= 1; 1202 buf += (top * srcPitch) + left; 1203 nlines = By2 - top; 1204 offset = (pPriv->area->box.y1 * pitch) + (top * dstPitch); 1205 1206#if DBUF 1207 if (pPriv->doubleBuffer && pPriv->currentBuffer) 1208 offset += (new_h >> 1) * pitch; 1209#endif 1210 1211 dst_start = pGeode->FBBase + offset + left; 1212 break; 1213 } 1214 s1offset = (top * srcPitch) + left; 1215 1216#if REINIT 1217 /* update cliplist */ 1218 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 1219 if (pPriv->colorKeyMode == 0) { 1220 /* draw these */ 1221 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 1222 } 1223 GX1DisplayVideo(pScrn, id, offset, width, height, dstPitch, 1224 Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, 1225 drw_h); 1226 } 1227#endif 1228 1229 switch (id) { 1230 1231 case FOURCC_Y800: 1232 GX1CopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 1233 break; 1234 case FOURCC_YV12: 1235 case FOURCC_I420: 1236 GX1CopyMungedData(buf + s1offset, buf + s2offset, 1237 buf + s3offset, dst_start, srcPitch, srcPitch2, 1238 dstPitch, nlines, npixels); 1239 break; 1240 case FOURCC_UYVY: 1241 case FOURCC_YUY2: 1242 default: 1243 GX1CopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 1244 break; 1245 } 1246#if !REINIT 1247 /* update cliplist */ 1248 REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 1249 if (pPriv->colorKeyMode == 0) { 1250 /* draw these */ 1251 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 1252 } 1253 GX1DisplayVideo(pScrn, id, offset, width, height, dstPitch, 1254 Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1255#endif 1256 1257#if XV_PROFILE 1258 UpdateCurrentTime(); 1259 newtime = currentTime.milliseconds; 1260 DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime)); 1261#endif 1262 1263#if DBUF 1264 pPriv->currentBuffer ^= 1; 1265#endif 1266 1267 pPriv->videoStatus = CLIENT_VIDEO_ON; 1268 pGeode->OverlayON = TRUE; 1269 return Success; 1270} 1271 1272/*---------------------------------------------------------------------------- 1273 * GX1QueryImageAttributes 1274 * 1275 * Description :This function is called to let the driver specify how data 1276 * for a particular image of size width by height should be 1277 * stored. 1278 * 1279 * Parameters. 1280 * pScreenInfo 1281 * Ptr :Screen handler pointer having screen information. 1282 * id :Id for the video format 1283 * width :width of the image (can be modified by the driver) 1284 * height :height of the image (can be modified by the driver) 1285 * Returns : Size of the memory required for storing this image 1286 * 1287 * Comments :None 1288 * 1289*---------------------------------------------------------------------------- 1290*/ 1291static int 1292GX1QueryImageAttributes(ScrnInfoPtr pScrn, 1293 int id, 1294 unsigned short *w, unsigned short *h, 1295 int *pitches, int *offsets) 1296{ 1297 int size; 1298 int tmp; 1299 1300 DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id)); 1301 1302 if (*w > 1024) 1303 *w = 1024; 1304 if (*h > 1024) 1305 *h = 1024; 1306 1307 *w = (*w + 1) & ~1; 1308 if (offsets) 1309 offsets[0] = 0; 1310 1311 switch (id) { 1312 case FOURCC_YV12: 1313 case FOURCC_I420: 1314 *h = (*h + 1) & ~1; 1315 size = (*w + 3) & ~3; 1316 if (pitches) 1317 pitches[0] = size; 1318 size *= *h; 1319 if (offsets) 1320 offsets[1] = size; 1321 tmp = ((*w >> 1) + 3) & ~3; 1322 if (pitches) 1323 pitches[1] = pitches[2] = tmp; 1324 tmp *= (*h >> 1); 1325 size += tmp; 1326 if (offsets) 1327 offsets[2] = size; 1328 size += tmp; 1329 break; 1330 case FOURCC_UYVY: 1331 case FOURCC_YUY2: 1332 case FOURCC_Y800: 1333 default: 1334 size = *w << 1; 1335 if (pitches) 1336 pitches[0] = size; 1337 size *= *h; 1338 break; 1339 } 1340 return size; 1341} 1342 1343static void 1344GX1BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) 1345{ 1346 ScreenPtr pScreen = screenInfo.screens[i]; 1347 ScrnInfoPtr pScrn = xf86Screens[i]; 1348 GeodePtr pGeode = GEODEPTR(pScrn); 1349 GeodePortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 1350 1351 DEBUGMSG(0, (0, X_NONE, "BlockHandler\n")); 1352 pScreen->BlockHandler = pGeode->BlockHandler; 1353 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 1354 pScreen->BlockHandler = GX1BlockHandler; 1355 1356 if (!pGeode->NoAccel) GX1AccelSync(pScrn); 1357 if (pPriv->videoStatus & TIMER_MASK) { 1358 UpdateCurrentTime(); 1359 if (pPriv->videoStatus & OFF_TIMER) { 1360 if (pPriv->offTime < currentTime.milliseconds) { 1361 GFX(set_video_enable(0)); 1362 pPriv->videoStatus = FREE_TIMER; 1363 pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1364 } 1365 } else { /* FREE_TIMER */ 1366 if (pPriv->freeTime < currentTime.milliseconds) { 1367 if (pPriv->area) { 1368 xf86FreeOffscreenArea(pPriv->area); 1369 pPriv->area = NULL; 1370 } 1371 pPriv->videoStatus = 0; 1372 } 1373 } 1374 } 1375} 1376 1377/****************** Offscreen stuff ***************/ 1378 1379typedef struct 1380{ 1381 FBAreaPtr area; 1382 FBLinearPtr linear; 1383 Bool isOn; 1384} 1385OffscreenPrivRec, *OffscreenPrivPtr; 1386 1387/*---------------------------------------------------------------------------- 1388 * GX1AllocateSurface 1389 * 1390 * Description :This function allocates an area of w by h in the offscreen 1391 * Parameters. 1392 * ScreenPtr 1393 * pScreen :Screen handler pointer having screen information. 1394 * 1395 * Returns :None 1396 * 1397 * Comments :None 1398 * 1399*---------------------------------------------------------------------------- 1400*/ 1401 1402static int 1403GX1AllocateSurface(ScrnInfoPtr pScrn, 1404 int id, 1405 unsigned short w, unsigned short h, XF86SurfacePtr surface) 1406{ 1407 FBAreaPtr area; 1408 int pitch, fbpitch, numlines; 1409 OffscreenPrivPtr pPriv; 1410 1411 DEBUGMSG(0, (0, X_NONE, "AllocateSurface %x\n", id)); 1412 if ((w > 1024) || (h > 1024)) 1413 return BadAlloc; 1414 1415 w = (w + 1) & ~1; 1416 pitch = ((w << 1) + 15) & ~15; 1417 fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; 1418 numlines = ((pitch * h) + fbpitch - 1) / fbpitch; 1419 1420 if (!(area = GX1AllocateMemory(pScrn, NULL, numlines))) 1421 return BadAlloc; 1422 1423 surface->width = w; 1424 surface->height = h; 1425 1426 if (!(surface->pitches = xalloc(sizeof(int)))) 1427 return BadAlloc; 1428 if (!(surface->offsets = xalloc(sizeof(int)))) { 1429 xfree(surface->pitches); 1430 return BadAlloc; 1431 } 1432 if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { 1433 xfree(surface->pitches); 1434 xfree(surface->offsets); 1435 return BadAlloc; 1436 } 1437 1438 pPriv->area = area; 1439 pPriv->isOn = FALSE; 1440 1441 surface->pScrn = pScrn; 1442 surface->id = id; 1443 surface->pitches[0] = pitch; 1444 surface->offsets[0] = area->box.y1 * fbpitch; 1445 surface->devPrivate.ptr = (pointer) pPriv; 1446 1447 return Success; 1448} 1449 1450static int 1451GX1StopSurface(XF86SurfacePtr surface) 1452{ 1453 OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; 1454 1455 if (pPriv->isOn) { 1456 pPriv->isOn = FALSE; 1457 } 1458 1459 return Success; 1460} 1461 1462static int 1463GX1FreeSurface(XF86SurfacePtr surface) 1464{ 1465 OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; 1466 1467 DEBUGMSG(0, (0, X_NONE, "FreeSurface\n")); 1468 1469 if (pPriv->isOn) 1470 GX1StopSurface(surface); 1471 xf86FreeOffscreenArea(pPriv->area); 1472 xfree(surface->pitches); 1473 xfree(surface->offsets); 1474 xfree(surface->devPrivate.ptr); 1475 1476 return Success; 1477} 1478 1479static int 1480GX1GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 * value) 1481{ 1482 return GX1GetPortAttribute(pScrn, attribute, value, 1483 (pointer) (GET_PORT_PRIVATE(pScrn))); 1484} 1485 1486static int 1487GX1SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value) 1488{ 1489 return GX1SetPortAttribute(pScrn, attribute, value, 1490 (pointer) (GET_PORT_PRIVATE(pScrn))); 1491} 1492 1493static int 1494GX1DisplaySurface(XF86SurfacePtr surface, 1495 short src_x, short src_y, 1496 short drw_x, short drw_y, 1497 short src_w, short src_h, 1498 short drw_w, short drw_h, RegionPtr clipBoxes) 1499{ 1500 OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; 1501 ScrnInfoPtr pScrn = surface->pScrn; 1502 GeodePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); 1503 INT32 x1, y1, x2, y2; 1504 BoxRec dstBox; 1505 1506 DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); 1507 x1 = src_x; 1508 x2 = src_x + src_w; 1509 y1 = src_y; 1510 y2 = src_y + src_h; 1511 1512 dstBox.x1 = drw_x; 1513 dstBox.x2 = drw_x + drw_w; 1514 dstBox.y1 = drw_y; 1515 dstBox.y2 = drw_y + drw_h; 1516 1517 if ((x1 >= x2) || (y1 >= y2)) 1518 return Success; 1519 1520 dstBox.x1 -= pScrn->frameX0; 1521 dstBox.x2 -= pScrn->frameX0; 1522 dstBox.y1 -= pScrn->frameY0; 1523 dstBox.y2 -= pScrn->frameY0; 1524 1525 xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 1526 1527 GX1DisplayVideo(pScrn, surface->id, surface->offsets[0], 1528 surface->width, surface->height, surface->pitches[0], 1529 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 1530 1531 pPriv->isOn = TRUE; 1532 if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 1533 REGION_EMPTY(pScrn->pScreen, &portPriv->clip); 1534 UpdateCurrentTime(); 1535 portPriv->videoStatus = FREE_TIMER; 1536 portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1537 } 1538 1539 return Success; 1540} 1541 1542/*---------------------------------------------------------------------------- 1543 * GX1InitOffscreenImages 1544 * 1545 * Description :This function sets up the offscreen memory management.It fills 1546 * in the XF86OffscreenImagePtr structure with functions to handle 1547 * offscreen memory operations. 1548 * 1549 * Parameters. 1550 * ScreenPtr 1551 * pScreen :Screen handler pointer having screen information. 1552 * 1553 * Returns : None 1554 * 1555 * Comments :None 1556 * 1557*---------------------------------------------------------------------------- 1558*/ 1559static void 1560GX1InitOffscreenImages(ScreenPtr pScreen) 1561{ 1562 XF86OffscreenImagePtr offscreenImages; 1563 1564 DEBUGMSG(0, (0, X_NONE, "InitOffscreenImages\n")); 1565 /* need to free this someplace */ 1566 if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) 1567 return; 1568 1569 offscreenImages[0].image = &Images[0]; 1570 offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1571 offscreenImages[0].alloc_surface = GX1AllocateSurface; 1572 offscreenImages[0].free_surface = GX1FreeSurface; 1573 offscreenImages[0].display = GX1DisplaySurface; 1574 offscreenImages[0].stop = GX1StopSurface; 1575 offscreenImages[0].setAttribute = GX1SetSurfaceAttribute; 1576 offscreenImages[0].getAttribute = GX1GetSurfaceAttribute; 1577 offscreenImages[0].max_width = 1024; 1578 offscreenImages[0].max_height = 1024; 1579 offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1580 offscreenImages[0].attributes = Attributes; 1581 1582 xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 1583} 1584