1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_video.c,v 1.6tsi Exp $ */ 2/* 3 * $Workfile: nsc_gx2_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 179#define DBUF 1 180void GX2InitVideo(ScreenPtr pScreen); 181void GX2ResetVideo(ScrnInfoPtr pScrn); 182static XF86VideoAdaptorPtr GX2SetupImageVideo(ScreenPtr); 183static void GX2InitOffscreenImages(ScreenPtr); 184static void GX2StopVideo(ScrnInfoPtr, pointer, Bool); 185static int GX2SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 186static int GX2GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); 187static void GX2QueryBestSize(ScrnInfoPtr, Bool, 188 short, short, short, short, unsigned int *, 189 unsigned int *, pointer); 190static int GX2PutImage(ScrnInfoPtr, short, short, short, short, short, short, 191 short, short, int, unsigned char *, short, short, Bool, 192 RegionPtr, pointer, DrawablePtr); 193static int GX2QueryImageAttributes(ScrnInfoPtr, int, unsigned short *, 194 unsigned short *, int *, int *); 195 196static void GX2BlockHandler(int, pointer, pointer, pointer); 197void GX2SetVideoPosition(int x, int y, int width, int height, 198 short src_w, short src_h, short drw_w, 199 short drw_h, int id, int offset, ScrnInfoPtr pScrn); 200 201extern void GX2AccelSync(ScrnInfoPtr pScreenInfo); 202 203#if !defined(STB_X) 204extern int DeltaX, DeltaY; 205#else 206int DeltaX, DeltaY; 207#endif 208 209#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 210 211static Atom xvColorKey, xvColorKeyMode, xvFilter 212#if DBUF 213 , xvDoubleBuffer 214#endif 215 ; 216 217/*---------------------------------------------------------------------------- 218 * GX2InitVideo 219 * 220 * Description :This is the initialization routine.It creates a new video adapter 221 * and calls GX2SetupImageVideo to initialize the adaptor by filling 222 * XF86VideoAdaptorREc.Then it lists the existing adaptors and adds the 223 * new one to it. Finally the list of XF86VideoAdaptorPtr pointers are 224 * passed to the xf86XVScreenInit(). 225 * 226 * Parameters. 227 * ScreenPtr 228 * pScreen :Screen handler pointer having screen information. 229 * 230 * Returns :none 231 * 232 * Comments :none 233 * 234*---------------------------------------------------------------------------- 235*/ 236void 237GX2InitVideo(ScreenPtr pScreen) 238{ 239 GeodePtr pGeode; 240 ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; 241 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 242 XF86VideoAdaptorPtr newAdaptor = NULL; 243 244 int num_adaptors; 245 246 pGeode = GEODEPTR(pScreenInfo); 247 248 newAdaptor = GX2SetupImageVideo(pScreen); 249 GX2InitOffscreenImages(pScreen); 250 251 num_adaptors = xf86XVListGenericAdaptors(pScreenInfo, &adaptors); 252 253 if (newAdaptor) { 254 if (!num_adaptors) { 255 num_adaptors = 1; 256 adaptors = &newAdaptor; 257 } else { 258 newAdaptors = /* need to free this someplace */ 259 xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); 260 if (newAdaptors) { 261 memcpy(newAdaptors, adaptors, num_adaptors * 262 sizeof(XF86VideoAdaptorPtr)); 263 newAdaptors[num_adaptors] = newAdaptor; 264 adaptors = newAdaptors; 265 num_adaptors++; 266 } 267 } 268 } 269 270 if (num_adaptors) 271 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 272 273 if (newAdaptors) 274 xfree(newAdaptors); 275} 276 277/* client libraries expect an encoding */ 278static XF86VideoEncodingRec DummyEncoding[1] = { 279 { 280 0, 281 "XV_IMAGE", 282 1024, 1024, 283 {1, 1} 284 } 285}; 286 287#define NUM_FORMATS 4 288 289static XF86VideoFormatRec Formats[NUM_FORMATS] = { 290 {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 291}; 292 293#if DBUF 294#define NUM_ATTRIBUTES 4 295#else 296#define NUM_ATTRIBUTES 3 297#endif 298 299static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { 300#if DBUF 301 {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 302#endif 303 {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 304 {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, 305 {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} 306}; 307 308#define NUM_IMAGES 7 309 310static XF86ImageRec Images[NUM_IMAGES] = { 311 XVIMAGE_UYVY, 312 XVIMAGE_YUY2, 313 XVIMAGE_Y2YU, 314 XVIMAGE_YVYU, 315 XVIMAGE_Y800, 316 XVIMAGE_I420, 317 XVIMAGE_YV12 318}; 319 320typedef struct 321{ 322 FBAreaPtr area; 323 FBLinearPtr linear; 324 RegionRec clip; 325 CARD32 colorKey; 326 CARD32 colorKeyMode; 327 CARD32 filter; 328 CARD32 videoStatus; 329 Time offTime; 330 Time freeTime; 331#if DBUF 332 Bool doubleBuffer; 333 int currentBuffer; 334#endif 335} 336GeodePortPrivRec, *GeodePortPrivPtr; 337 338#define GET_PORT_PRIVATE(pScrn) \ 339 (GeodePortPrivPtr)((GEODEPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 340 341/*---------------------------------------------------------------------------- 342 * GX2SetColorKey 343 * 344 * Description :This function reads the color key for the pallete and 345 * sets the video color key register. 346 * 347 * Parameters. 348 * ScreenInfoPtr 349 * pScrn :Screen pointer having screen information. 350 * pPriv :Video port private data 351 * 352 * Returns :none 353 * 354 * Comments :none 355 * 356*---------------------------------------------------------------------------- 357*/ 358static INT32 359GX2SetColorkey(ScrnInfoPtr pScrn, GeodePortPrivPtr pPriv) 360{ 361 int red, green, blue; 362 unsigned long key; 363 364 switch (pScrn->depth) { 365 case 8: 366 GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key)); 367 red = ((key >> 16) & 0xFF); 368 green = ((key >> 8) & 0xFF); 369 blue = (key & 0xFF); 370 break; 371 case 16: 372 red = (pPriv->colorKey & pScrn->mask.red) >> 373 pScrn->offset.red << (8 - pScrn->weight.red); 374 green = (pPriv->colorKey & pScrn->mask.green) >> 375 pScrn->offset.green << (8 - pScrn->weight.green); 376 blue = (pPriv->colorKey & pScrn->mask.blue) >> 377 pScrn->offset.blue << (8 - pScrn->weight.blue); 378 break; 379 default: 380 /* for > 16 bpp we send in the mask in xf86SetWeight. This 381 * function is providing the offset by 1 more. So we take 382 * this as a special case and subtract 1 for > 16 383 */ 384 red = (pPriv->colorKey & pScrn->mask.red) >> 385 (pScrn->offset.red - 1) << (8 - pScrn->weight.red); 386 green = (pPriv->colorKey & pScrn->mask.green) >> 387 (pScrn->offset.green - 1) << (8 - pScrn->weight.green); 388 blue = (pPriv->colorKey & pScrn->mask.blue) >> 389 (pScrn->offset.blue - 1) << (8 - pScrn->weight.blue); 390 break; 391 } 392 393 GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFFFFFF, 394 (pPriv->colorKeyMode == 0))); 395 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 396 return 0; 397} 398 399/*---------------------------------------------------------------------------- 400 * GX2ResetVideo 401 * 402 * Description : This function resets the video 403 * 404 * Parameters. 405 * ScreenInfoPtr 406 * pScrn :Screen pointer having screen information. 407 * 408 * Returns :None 409 * 410 * Comments :none 411 * 412*---------------------------------------------------------------------------- 413*/ 414 415void 416GX2ResetVideo(ScrnInfoPtr pScrn) 417{ 418 GeodePtr pGeode = GEODEPTR(pScrn); 419 420 GeodePortPrivPtr pPriv = pGeode->adaptor->pPortPrivates[0].ptr; 421 422 if (!pGeode->NoAccel) GX2AccelSync(pScrn); 423 GFX(set_video_palette(NULL)); 424 GX2SetColorkey(pScrn, pPriv); 425 GFX(set_video_filter(pPriv->filter, pPriv->filter)); 426} 427 428/*---------------------------------------------------------------------------- 429 * GX2SetupImageVideo 430 * 431 * Description : This function allocates space for a Videoadaptor and initializes 432 * the XF86VideoAdaptorPtr record. 433 * 434 * Parameters. 435 * ScreenPtr 436 * pScreen :Screen handler pointer having screen information. 437 * 438 * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record. 439 * 440 * Comments :none 441 * 442*---------------------------------------------------------------------------- 443*/ 444 445static XF86VideoAdaptorPtr 446GX2SetupImageVideo(ScreenPtr pScreen) 447{ 448 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 449 GeodePtr pGeode = GEODEPTR(pScrn); 450 XF86VideoAdaptorPtr adapt; 451 GeodePortPrivPtr pPriv; 452 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 = GX2StopVideo; 477 adapt->SetPortAttribute = GX2SetPortAttribute; 478 adapt->GetPortAttribute = GX2GetPortAttribute; 479 adapt->QueryBestSize = GX2QueryBestSize; 480 adapt->PutImage = GX2PutImage; 481 adapt->QueryImageAttributes = GX2QueryImageAttributes; 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 = GX2BlockHandler; 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 GX2ResetVideo(pScrn); 508 509 return adapt; 510} 511 512/*---------------------------------------------------------------------------- 513 * GX2StopVideo 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 530GX2StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) 531{ 532 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 533 GeodePtr pGeode = GEODEPTR(pScrn); 534 535 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 536 537 if (!pGeode->NoAccel) GX2AccelSync(pScrn); 538 if (exit) { 539 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 540 GFX(set_video_enable(0)); 541 } 542 if (pPriv->area) { 543 xf86FreeOffscreenArea(pPriv->area); 544 pPriv->area = NULL; 545 } 546 pPriv->videoStatus = 0; 547 pGeode->OverlayON = FALSE; 548 } else { 549 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 550 pPriv->videoStatus |= OFF_TIMER; 551 pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 552 } 553 } 554} 555 556/*---------------------------------------------------------------------------- 557 * GX2SetPortAttribute 558 * 559 * Description :This function is used to set the attributes of a port like colorkeymode, 560 * double buffer support and filter. 561 * 562 * Parameters. 563 * pScreenInfo 564 * Ptr :Screen handler pointer having screen information. 565 * data :Pointer to the video port's private data 566 * attribute :The port attribute to be set 567 * value :Value of the attribute to be set. 568 * 569 * Returns :Sucess if the attribute is supported, else BadMatch 570 * 571 * Comments :none 572 * 573*---------------------------------------------------------------------------- 574*/ 575static int 576GX2SetPortAttribute(ScrnInfoPtr pScrn, 577 Atom attribute, INT32 value, pointer data) 578{ 579 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 580 GeodePtr pGeode = GEODEPTR(pScrn); 581 582 if (!pGeode->NoAccel) GX2AccelSync(pScrn); 583 if (attribute == xvColorKey) { 584 pPriv->colorKey = value; 585 GX2SetColorkey(pScrn, pPriv); 586 } 587#if DBUF 588 else if (attribute == xvDoubleBuffer) { 589 if ((value < 0) || (value > 1)) 590 return BadValue; 591 pPriv->doubleBuffer = value; 592 } 593#endif 594 else if (attribute == xvColorKeyMode) { 595 pPriv->colorKeyMode = value; 596 GX2SetColorkey(pScrn, pPriv); 597 } else if (attribute == xvFilter) { 598 pPriv->filter = value; 599 GFX(set_video_filter(pPriv->filter, pPriv->filter)); 600 } else 601 return BadMatch; 602 603 return Success; 604} 605 606/*---------------------------------------------------------------------------- 607 * GX2GetPortAttribute 608 * 609 * Description :This function is used to get the attributes of a port like hue, 610 * saturation,brightness or contrast. 611 * 612 * Parameters. 613 * pScreenInfo 614 * Ptr :Screen handler pointer having screen information. 615 * data :Pointer to the video port's private data 616 * attribute :The port attribute to be read 617 * value :Pointer to the value of the attribute to be read. 618 * 619 * Returns :Sucess if the attribute is supported, else BadMatch 620 * 621 * Comments :none 622 * 623*---------------------------------------------------------------------------- 624*/ 625static int 626GX2GetPortAttribute(ScrnInfoPtr pScrn, 627 Atom attribute, INT32 * value, pointer data) 628{ 629 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 630 631 if (attribute == xvColorKey) { 632 *value = pPriv->colorKey; 633 } 634#if DBUF 635 else if (attribute == xvDoubleBuffer) { 636 *value = (pPriv->doubleBuffer) ? 1 : 0; 637 } 638#endif 639 else if (attribute == xvColorKeyMode) { 640 *value = pPriv->colorKeyMode; 641 } else if (attribute == xvFilter) { 642 *value = pPriv->filter; 643 } else 644 return BadMatch; 645 646 return Success; 647} 648 649/*---------------------------------------------------------------------------- 650 * GX2QueryBestSize 651 * 652 * Description :This function provides a way to query what the destination dimensions 653 * would end up being if they were to request that an area vid_w by vid_h 654 * from the video stream be scaled to rectangle of drw_w by drw_h on 655 * the screen. 656 * 657 * Parameters. 658 * ScreenInfoPtr 659 * pScrn :Screen handler pointer having screen information. 660 * data :Pointer to the video port's private data 661 * vid_w,vid_h :Width and height of the video data. 662 * drw_w,drw_h :Width and height of the scaled rectangle. 663 * p_w,p_h :Width and height of the destination rectangle. 664 * 665 * Returns :None 666 * 667 * Comments :None 668 * 669*---------------------------------------------------------------------------- 670*/ 671static void 672GX2QueryBestSize(ScrnInfoPtr pScrn, 673 Bool motion, 674 short vid_w, short vid_h, 675 short drw_w, short drw_h, 676 unsigned int *p_w, unsigned int *p_h, pointer data) 677{ 678 *p_w = drw_w; 679 *p_h = drw_h; 680 681 if (*p_w > 16384) 682 *p_w = 16384; 683} 684 685static void 686GX2CopyGreyscale(unsigned char *src, 687 unsigned char *dst, int srcPitch, int dstPitch, int h, int w) 688{ 689 int i; 690 unsigned char *src2 = src; 691 unsigned char *dst2 = dst; 692 unsigned char *dst3; 693 unsigned char *src3; 694 695 dstPitch <<= 1; 696 697 while (h--) { 698 dst3 = dst2; 699 src3 = src2; 700 for (i = 0; i < w; i++) { 701 *dst3++ = *src3++; /* Copy Y data */ 702 *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ 703 } 704 src3 = src2; 705 for (i = 0; i < w; i++) { 706 *dst3++ = *src3++; /* Copy Y data */ 707 *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ 708 } 709 dst2 += dstPitch; 710 src2 += srcPitch; 711 } 712} 713 714/*---------------------------------------------------------------------------- 715 * GX2CopyData420 716 * 717 * Description : Copies data from src to destination 718 * 719 * Parameters. 720 * src : pointer to the source data 721 * dst : pointer to destination data 722 * srcPitch : pitch of the srcdata 723 * dstPitch : pitch of the destination data 724 * h & w : height and width of source data 725 * 726 * Returns :None 727 * 728 * Comments :None 729 * 730*---------------------------------------------------------------------------- 731*/ 732 733static void 734GX2CopyData420(unsigned char *src, unsigned char *dst, 735 int srcPitch, int dstPitch, int h, int w) 736{ 737 while (h--) { 738 memcpy(dst, src, w); 739 src += srcPitch; 740 dst += dstPitch; 741 } 742} 743 744/*---------------------------------------------------------------------------- 745 * GX2CopyData422 746 * 747 * Description : Copies data from src to destination 748 * 749 * Parameters. 750 * src : pointer to the source data 751 * dst : pointer to destination data 752 * srcPitch : pitch of the srcdata 753 * dstPitch : pitch of the destination data 754 * h & w : height and width of source data 755 * 756 * Returns :None 757 * 758 * Comments :None 759 * 760*---------------------------------------------------------------------------- 761*/ 762 763static void 764GX2CopyData422(unsigned char *src, unsigned char *dst, 765 int srcPitch, int dstPitch, int h, int w) 766{ 767 w <<= 1; 768 while (h--) { 769 memcpy(dst, src, w); 770 src += srcPitch; 771 dst += dstPitch; 772 } 773} 774 775static FBAreaPtr 776GX2AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int numlines) 777{ 778 ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; 779 FBAreaPtr new_area; 780 781 if (area) { 782 if ((area->box.y2 - area->box.y1) >= numlines) 783 return area; 784 785 if (xf86ResizeOffscreenArea(area, pScrn->displayWidth, numlines)) 786 return area; 787 788 xf86FreeOffscreenArea(area); 789 } 790 791 new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, 792 numlines, 0, NULL, NULL, NULL); 793 794 if (!new_area) { 795 int max_w, max_h; 796 797 xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, 798 FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); 799 800 if ((max_w < pScrn->displayWidth) || (max_h < numlines)) 801 return NULL; 802 803 xf86PurgeUnlockedOffscreenAreas(pScreen); 804 new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, 805 numlines, 0, NULL, NULL, NULL); 806 } 807 808 return new_area; 809} 810 811static BoxRec dstBox; 812static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; 813static INT32 Bx1, Bx2, By1, By2; 814static int top, left, npixels, nlines; 815static int offset, s1offset = 0, s2offset = 0, s3offset = 0; 816static unsigned char *dst_start; 817static int d2offset = 0, d3offset = 0; 818static Bool 819RegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult) 820{ 821 pRclResult->x1 = max(pRcl1->x1, pRcl2->x1); 822 pRclResult->x2 = min(pRcl1->x2, pRcl2->x2); 823 824 if (pRclResult->x1 <= pRclResult->x2) { 825 pRclResult->y1 = max(pRcl1->y1, pRcl2->y1); 826 pRclResult->y2 = min(pRcl1->y2, pRcl2->y2); 827 828 if (pRclResult->y1 <= pRclResult->y2) { 829 return (TRUE); 830 } 831 } 832 833 return (FALSE); 834} 835 836void 837GX2SetVideoPosition(int x, int y, int width, int height, 838 short src_w, short src_h, short drw_w, short drw_h, 839 int id, int offset, ScrnInfoPtr pScrn) 840{ 841 GeodePtr pGeode = GEODEPTR(pScrn); 842 long xstart, ystart, xend, yend; 843 unsigned long lines = 0; 844 unsigned long y_extra, uv_extra = 0; 845 BoxRec ovly, display, result; 846 847#if defined(STB_X) 848 unsigned long startAddress = 0; 849#endif 850 851 xend = x + drw_w; 852 yend = y + drw_h; 853 854 /* Take care of panning when panel is present */ 855 856#if defined(STB_X) 857 Gal_get_display_offset(&startAddress); 858 DeltaY = startAddress / pGeode->Pitch; 859 DeltaX = startAddress & (pGeode->Pitch - 1); 860 DeltaX /= (pScrn->bitsPerPixel >> 3); 861#endif 862 863 if (pGeode->Panel) { 864 ovly.x1 = x; 865 ovly.x2 = x + pGeode->video_dstw; 866 ovly.y1 = y; 867 ovly.y2 = y + pGeode->video_dsth; 868 869 display.x1 = DeltaX; 870 display.x2 = DeltaX + pGeode->FPBX; 871 display.y1 = DeltaY; 872 display.y2 = DeltaY + pGeode->FPBY; 873 x = xend = 0; 874 if (RegionsIntersect(&display, &ovly, &result)) { 875 x = ovly.x1 - DeltaX; 876 xend = ovly.x2 - DeltaX; 877 y = ovly.y1 - DeltaY; 878 yend = ovly.y2 - DeltaY; 879 } 880 } 881 882 /* LEFT CLIPPING */ 883 884 if (x < 0) { 885 xstart = 0; 886 } else { 887 xstart = (unsigned long)x; 888 } 889 drw_w -= (xstart - x); 890 891 /* TOP CLIPPING */ 892 893 if (y < 0) { 894 lines = (-y) * src_h / drw_h; 895 ystart = 0; 896 drw_h += y; 897 y_extra = lines * dstPitch; 898 uv_extra = (lines >> 1) * (dstPitch2); 899 } else { 900 ystart = y; 901 lines = 0; 902 y_extra = 0; 903 } 904 GFX(set_video_window(xstart, ystart, xend - xstart, yend - ystart)); 905 if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { 906 GFX(set_video_yuv_offsets(offset + y_extra, 907 offset + d3offset + uv_extra, 908 offset + d2offset + uv_extra)); 909 } else { 910 GFX(set_video_offset(offset + y_extra)); 911 } 912 GFX(set_video_left_crop(xstart - x)); 913} 914 915/*---------------------------------------------------------------------------- 916 * GX2DisplayVideo 917 * 918 * Description : This function sets up the video registers for playing video 919 * It sets up the video format,width, height & position of the 920 * video window ,video offsets( y,u,v) and video pitches(y,u,v) 921 * Parameters. 922 * 923 * Returns :None 924 * 925 * Comments :None 926 * 927*---------------------------------------------------------------------------- 928*/ 929 930static void 931GX2DisplayVideo(ScrnInfoPtr pScrn, 932 int id, 933 int offset, 934 short width, short height, 935 int pitch, 936 int x1, int y1, int x2, int y2, 937 BoxPtr dstBox, 938 short src_w, short src_h, short drw_w, short drw_h) 939{ 940 GeodePtr pGeode = GEODEPTR(pScrn); 941 942 if (!pGeode->NoAccel) GX2AccelSync(pScrn); 943 944 GFX(set_video_enable(1)); 945 946 switch (id) { 947 case FOURCC_UYVY: /* UYVY */ 948 GFX(set_video_format(VIDEO_FORMAT_UYVY)); 949 GFX(set_video_size(width, height)); 950 break; 951 case FOURCC_Y800: /* Y800 - greyscale - we munge it! */ 952 case FOURCC_YV12: /* YV12 */ 953 case FOURCC_I420: /* I420 */ 954 GFX(set_video_format(VIDEO_FORMAT_Y0Y1Y2Y3)); 955 GFX(set_video_size(width, height)); 956 GFX(set_video_yuv_pitch(dstPitch, dstPitch2)); 957 break; 958 case FOURCC_YUY2: /* YUY2 */ 959 GFX(set_video_format(VIDEO_FORMAT_YUYV)); 960 GFX(set_video_size(width, height)); 961 break; 962 case FOURCC_Y2YU: /* Y2YU */ 963 GFX(set_video_format(VIDEO_FORMAT_Y2YU)); 964 GFX(set_video_size(width, height)); 965 break; 966 case FOURCC_YVYU: /* YVYU */ 967 GFX(set_video_format(VIDEO_FORMAT_YVYU)); 968 GFX(set_video_size(width, height)); 969 break; 970 } 971 if (pGeode->Panel) { 972 pGeode->video_x = dstBox->x1; 973 pGeode->video_y = dstBox->y1; 974 pGeode->video_w = width; 975 pGeode->video_h = height; 976 pGeode->video_srcw = src_w; 977 pGeode->video_srch = src_h; 978 pGeode->video_dstw = drw_w; 979 pGeode->video_dsth = drw_h; 980 pGeode->video_offset = offset; 981 pGeode->video_id = id; 982 pGeode->video_scrnptr = pScrn; 983 } 984 GFX(set_video_scale(width, height, drw_w, drw_h)); 985 GX2SetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, 986 src_h, drw_w, drw_h, id, offset, pScrn); 987 988} 989 990/*---------------------------------------------------------------------------- 991 * GX2PutImage : This function writes a single frame of video into a drawable. 992 * The position and size of the source rectangle is specified by src_x,src_y, 993 * src_w and src_h. This data is stored in a system memory buffer at buf. 994 * The position and size of the destination rectangle is specified by drw_x, 995 * drw_y,drw_w,drw_h.The data is in the format indicated by the image descriptor 996 * and represents a source of size width by height. If sync is TRUE the driver 997 * should not return from this function until it is through reading the data from 998 * buf. Returning when sync is TRUE indicates that it is safe for the data at buf 999 * to be replaced,freed, or modified. 1000 * 1001 * 1002 * Description : 1003 * Parameters. 1004 * 1005 * Returns :None 1006 * 1007 * Comments :None 1008 * 1009*---------------------------------------------------------------------------- 1010*/ 1011 1012static int 1013GX2PutImage(ScrnInfoPtr pScrn, 1014 short src_x, short src_y, 1015 short drw_x, short drw_y, 1016 short src_w, short src_h, 1017 short drw_w, short drw_h, 1018 int id, unsigned char *buf, 1019 short width, short height, 1020 Bool sync, RegionPtr clipBoxes, pointer data, 1021 DrawablePtr pDraw) 1022{ 1023 GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; 1024 GeodePtr pGeode = GEODEPTR(pScrn); 1025 int new_h; 1026 1027#if REINIT 1028 BOOL ReInitVideo = FALSE; 1029#endif 1030 1031#if XV_PROFILE 1032 long oldtime, newtime; 1033 1034 UpdateCurrentTime(); 1035 oldtime = currentTime.milliseconds; 1036#endif 1037 1038#if REINIT 1039/* update cliplist */ 1040 if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 1041 ReInitVideo = TRUE; 1042 } 1043 if (ReInitVideo) { 1044 DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n")); 1045#endif 1046 1047 if (drw_w > 16384) 1048 drw_w = 16384; 1049 1050 /* Clip */ 1051 Bx1 = src_x; 1052 Bx2 = src_x + src_w; 1053 By1 = src_y; 1054 By2 = src_y + src_h; 1055 1056 if ((Bx1 >= Bx2) || (By1 >= By2)) 1057 return Success; 1058 1059 dstBox.x1 = drw_x; 1060 dstBox.x2 = drw_x + drw_w; 1061 dstBox.y1 = drw_y; 1062 dstBox.y2 = drw_y + drw_h; 1063 1064 dstBox.x1 -= pScrn->frameX0; 1065 dstBox.x2 -= pScrn->frameX0; 1066 dstBox.y1 -= pScrn->frameY0; 1067 dstBox.y2 -= pScrn->frameY0; 1068 1069 switch (id) { 1070 case FOURCC_YV12: 1071 case FOURCC_I420: 1072 1073 srcPitch = (width + 3) & ~3; /* of luma */ 1074 dstPitch = (width + 31) & ~31; 1075 1076 s2offset = srcPitch * height; 1077 d2offset = dstPitch * height; 1078 1079 srcPitch2 = ((width >> 1) + 3) & ~3; 1080 dstPitch2 = ((width >> 1) + 15) & ~15; 1081 1082 s3offset = (srcPitch2 * (height >> 1)) + s2offset; 1083 d3offset = (dstPitch2 * (height >> 1)) + d2offset; 1084 1085 new_h = dstPitch * height; /* Y */ 1086 new_h += (dstPitch2 * height); /* U+V */ 1087 new_h += pGeode->Pitch - 1; 1088 new_h /= pGeode->Pitch; 1089 break; 1090 1091 case FOURCC_UYVY: 1092 case FOURCC_YUY2: 1093 case FOURCC_Y800: 1094 default: 1095 dstPitch = ((width << 1) + 3) & ~3; 1096 srcPitch = (width << 1); 1097 new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; 1098 break; 1099 } 1100 1101#if DBUF 1102 if (pPriv->doubleBuffer) 1103 new_h <<= 1; 1104#endif 1105 1106 if (!(pPriv->area = GX2AllocateMemory(pScrn, pPriv->area, new_h))) 1107 return BadAlloc; 1108 1109 /* copy data */ 1110 top = By1; 1111 left = Bx1 & ~1; 1112 npixels = ((Bx2 + 1) & ~1) - left; 1113 1114 switch (id) { 1115 case FOURCC_YV12: 1116 case FOURCC_I420: 1117 { 1118 int tmp; 1119 1120 top &= ~1; 1121 offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch); 1122 1123#if DBUF 1124 if (pPriv->doubleBuffer && pPriv->currentBuffer) 1125 offset += (new_h >> 1) * pGeode->Pitch; 1126#endif 1127 1128 dst_start = pGeode->FBBase + offset + left; 1129 tmp = ((top >> 1) * srcPitch2) + (left >> 1); 1130 s2offset += tmp; 1131 s3offset += tmp; 1132 if (id == FOURCC_I420) { 1133 tmp = s2offset; 1134 s2offset = s3offset; 1135 s3offset = tmp; 1136 } 1137 nlines = ((By2 + 1) & ~1) - top; 1138 } 1139 break; 1140 case FOURCC_UYVY: 1141 case FOURCC_YUY2: 1142 case FOURCC_Y800: 1143 default: 1144 left <<= 1; 1145 buf += (top * srcPitch) + left; 1146 nlines = By2 - top; 1147 offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch); 1148#if DBUF 1149 if (pPriv->doubleBuffer && pPriv->currentBuffer) 1150 offset += (new_h >> 1) * pGeode->Pitch; 1151#endif 1152 1153 dst_start = pGeode->FBBase + offset + left; 1154 break; 1155 } 1156 s1offset = (top * srcPitch) + left; 1157 1158#if REINIT 1159 /* update cliplist */ 1160 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 1161 if (pPriv->colorKeyMode == 0) { 1162 /* draw these */ 1163 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 1164 } 1165 GX2DisplayVideo(pScrn, id, offset, width, height, dstPitch, 1166 Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, 1167 drw_h); 1168 } 1169#endif 1170 1171 switch (id) { 1172 1173 case FOURCC_Y800: 1174 GX2CopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 1175 break; 1176 case FOURCC_YV12: 1177 case FOURCC_I420: 1178 GX2CopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, 1179 npixels); 1180 GX2CopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, 1181 dstPitch2, nlines >> 1, npixels >> 1); 1182 GX2CopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, 1183 dstPitch2, nlines >> 1, npixels >> 1); 1184 break; 1185 case FOURCC_UYVY: 1186 case FOURCC_YUY2: 1187 default: 1188 GX2CopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 1189 break; 1190 } 1191#if !REINIT 1192 /* update cliplist */ 1193 REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 1194 if (pPriv->colorKeyMode == 0) { 1195 /* draw these */ 1196 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 1197 } 1198 GX2DisplayVideo(pScrn, id, offset, width, height, dstPitch, 1199 Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1200#endif 1201 1202#if XV_PROFILE 1203 UpdateCurrentTime(); 1204 newtime = currentTime.milliseconds; 1205 DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime)); 1206#endif 1207 1208#if DBUF 1209 pPriv->currentBuffer ^= 1; 1210#endif 1211 1212 pPriv->videoStatus = CLIENT_VIDEO_ON; 1213 pGeode->OverlayON = TRUE; 1214 return Success; 1215} 1216 1217/*---------------------------------------------------------------------------- 1218 * GX2QueryImageAttributes 1219 * 1220 * Description :This function is called to let the driver specify how data 1221 * for a particular image of size width by height should be 1222 * stored. 1223 * 1224 * Parameters. 1225 * pScreenInfo 1226 * Ptr :Screen handler pointer having screen information. 1227 * id :Id for the video format 1228 * width :width of the image (can be modified by the driver) 1229 * height :height of the image (can be modified by the driver) 1230 * Returns : Size of the memory required for storing this image 1231 * 1232 * Comments :None 1233 * 1234*---------------------------------------------------------------------------- 1235*/ 1236static int 1237GX2QueryImageAttributes(ScrnInfoPtr pScrn, 1238 int id, 1239 unsigned short *w, unsigned short *h, 1240 int *pitches, int *offsets) 1241{ 1242 int size; 1243 int tmp; 1244 1245 DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id)); 1246 1247 if (*w > 1024) 1248 *w = 1024; 1249 if (*h > 1024) 1250 *h = 1024; 1251 1252 *w = (*w + 1) & ~1; 1253 if (offsets) 1254 offsets[0] = 0; 1255 1256 switch (id) { 1257 case FOURCC_YV12: 1258 case FOURCC_I420: 1259 *h = (*h + 1) & ~1; 1260 size = (*w + 3) & ~3; 1261 if (pitches) 1262 pitches[0] = size; 1263 size *= *h; 1264 if (offsets) 1265 offsets[1] = size; 1266 tmp = ((*w >> 1) + 3) & ~3; 1267 if (pitches) 1268 pitches[1] = pitches[2] = tmp; 1269 tmp *= (*h >> 1); 1270 size += tmp; 1271 if (offsets) 1272 offsets[2] = size; 1273 size += tmp; 1274 break; 1275 case FOURCC_UYVY: 1276 case FOURCC_YUY2: 1277 case FOURCC_Y800: 1278 default: 1279 size = *w << 1; 1280 if (pitches) 1281 pitches[0] = size; 1282 size *= *h; 1283 break; 1284 } 1285 return size; 1286} 1287 1288static void 1289GX2BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) 1290{ 1291 ScreenPtr pScreen = screenInfo.screens[i]; 1292 ScrnInfoPtr pScrn = xf86Screens[i]; 1293 GeodePtr pGeode = GEODEPTR(pScrn); 1294 GeodePortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 1295 1296 pScreen->BlockHandler = pGeode->BlockHandler; 1297 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 1298 pScreen->BlockHandler = GX2BlockHandler; 1299 1300 if (!pGeode->NoAccel) GX2AccelSync(pScrn); 1301 if (pPriv->videoStatus & TIMER_MASK) { 1302 UpdateCurrentTime(); 1303 if (pPriv->videoStatus & OFF_TIMER) { 1304 if (pPriv->offTime < currentTime.milliseconds) { 1305 GFX(set_video_enable(0)); 1306 pPriv->videoStatus = FREE_TIMER; 1307 pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1308 } 1309 } else { /* FREE_TIMER */ 1310 if (pPriv->freeTime < currentTime.milliseconds) { 1311 if (pPriv->area) { 1312 xf86FreeOffscreenArea(pPriv->area); 1313 pPriv->area = NULL; 1314 } 1315 pPriv->videoStatus = 0; 1316 } 1317 } 1318 } 1319} 1320 1321/****************** Offscreen stuff ***************/ 1322 1323typedef struct 1324{ 1325 FBAreaPtr area; 1326 FBLinearPtr linear; 1327 Bool isOn; 1328} 1329OffscreenPrivRec, *OffscreenPrivPtr; 1330 1331/*---------------------------------------------------------------------------- 1332 * GX2AllocateSurface 1333 * 1334 * Description :This function allocates an area of w by h in the offscreen 1335 * Parameters. 1336 * ScreenPtr 1337 * pScreen :Screen handler pointer having screen information. 1338 * 1339 * Returns :None 1340 * 1341 * Comments :None 1342 * 1343*---------------------------------------------------------------------------- 1344*/ 1345 1346static int 1347GX2AllocateSurface(ScrnInfoPtr pScrn, 1348 int id, 1349 unsigned short w, unsigned short h, XF86SurfacePtr surface) 1350{ 1351 FBAreaPtr area; 1352 int pitch, fbpitch, numlines; 1353 OffscreenPrivPtr pPriv; 1354 1355 if ((w > 1024) || (h > 1024)) 1356 return BadAlloc; 1357 1358 w = (w + 1) & ~1; 1359 pitch = ((w << 1) + 15) & ~15; 1360 fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; 1361 numlines = ((pitch * h) + fbpitch - 1) / fbpitch; 1362 1363 if (!(area = GX2AllocateMemory(pScrn, NULL, numlines))) 1364 return BadAlloc; 1365 1366 surface->width = w; 1367 surface->height = h; 1368 1369 if (!(surface->pitches = xalloc(sizeof(int)))) 1370 return BadAlloc; 1371 if (!(surface->offsets = xalloc(sizeof(int)))) { 1372 xfree(surface->pitches); 1373 return BadAlloc; 1374 } 1375 if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { 1376 xfree(surface->pitches); 1377 xfree(surface->offsets); 1378 return BadAlloc; 1379 } 1380 1381 pPriv->area = area; 1382 pPriv->isOn = FALSE; 1383 1384 surface->pScrn = pScrn; 1385 surface->id = id; 1386 surface->pitches[0] = pitch; 1387 surface->offsets[0] = area->box.y1 * fbpitch; 1388 surface->devPrivate.ptr = (pointer) pPriv; 1389 1390 return Success; 1391} 1392 1393static int 1394GX2StopSurface(XF86SurfacePtr surface) 1395{ 1396 OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; 1397 1398 if (pPriv->isOn) { 1399 pPriv->isOn = FALSE; 1400 } 1401 1402 return Success; 1403} 1404 1405static int 1406GX2FreeSurface(XF86SurfacePtr surface) 1407{ 1408 OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; 1409 1410 if (pPriv->isOn) 1411 GX2StopSurface(surface); 1412 xf86FreeOffscreenArea(pPriv->area); 1413 xfree(surface->pitches); 1414 xfree(surface->offsets); 1415 xfree(surface->devPrivate.ptr); 1416 1417 return Success; 1418} 1419 1420static int 1421GX2GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 * value) 1422{ 1423 return GX2GetPortAttribute(pScrn, attribute, value, 1424 (pointer) (GET_PORT_PRIVATE(pScrn))); 1425} 1426 1427static int 1428GX2SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value) 1429{ 1430 return GX2SetPortAttribute(pScrn, attribute, value, 1431 (pointer) (GET_PORT_PRIVATE(pScrn))); 1432} 1433 1434static int 1435GX2DisplaySurface(XF86SurfacePtr surface, 1436 short src_x, short src_y, 1437 short drw_x, short drw_y, 1438 short src_w, short src_h, 1439 short drw_w, short drw_h, RegionPtr clipBoxes) 1440{ 1441 OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; 1442 ScrnInfoPtr pScrn = surface->pScrn; 1443 GeodePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); 1444 INT32 x1, y1, x2, y2; 1445 BoxRec dstBox; 1446 1447 DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); 1448 x1 = src_x; 1449 x2 = src_x + src_w; 1450 y1 = src_y; 1451 y2 = src_y + src_h; 1452 1453 dstBox.x1 = drw_x; 1454 dstBox.x2 = drw_x + drw_w; 1455 dstBox.y1 = drw_y; 1456 dstBox.y2 = drw_y + drw_h; 1457 1458 if ((x1 >= x2) || (y1 >= y2)) 1459 return Success; 1460 1461 dstBox.x1 -= pScrn->frameX0; 1462 dstBox.x2 -= pScrn->frameX0; 1463 dstBox.y1 -= pScrn->frameY0; 1464 dstBox.y2 -= pScrn->frameY0; 1465 1466 xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 1467 1468 GX2DisplayVideo(pScrn, surface->id, surface->offsets[0], 1469 surface->width, surface->height, surface->pitches[0], 1470 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 1471 1472 pPriv->isOn = TRUE; 1473 if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 1474 REGION_EMPTY(pScrn->pScreen, &portPriv->clip); 1475 UpdateCurrentTime(); 1476 portPriv->videoStatus = FREE_TIMER; 1477 portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1478 } 1479 1480 return Success; 1481} 1482 1483/*---------------------------------------------------------------------------- 1484 * GX2InitOffscreenImages 1485 * 1486 * Description :This function sets up the offscreen memory management.It fills 1487 * in the XF86OffscreenImagePtr structure with functions to handle 1488 * offscreen memory operations. 1489 * 1490 * Parameters. 1491 * ScreenPtr 1492 * pScreen :Screen handler pointer having screen information. 1493 * 1494 * Returns : None 1495 * 1496 * Comments :None 1497 * 1498*---------------------------------------------------------------------------- 1499*/ 1500static void 1501GX2InitOffscreenImages(ScreenPtr pScreen) 1502{ 1503 XF86OffscreenImagePtr offscreenImages; 1504 1505 /* need to free this someplace */ 1506 if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) 1507 return; 1508 1509 offscreenImages[0].image = &Images[0]; 1510 offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1511 offscreenImages[0].alloc_surface = GX2AllocateSurface; 1512 offscreenImages[0].free_surface = GX2FreeSurface; 1513 offscreenImages[0].display = GX2DisplaySurface; 1514 offscreenImages[0].stop = GX2StopSurface; 1515 offscreenImages[0].setAttribute = GX2SetSurfaceAttribute; 1516 offscreenImages[0].getAttribute = GX2GetSurfaceAttribute; 1517 offscreenImages[0].max_width = 1024; 1518 offscreenImages[0].max_height = 1024; 1519 offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1520 offscreenImages[0].attributes = Attributes; 1521 1522 xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 1523} 1524