i830_video.c

来自「是由intel提供的针对intel显卡915以上系列的linux驱动」· C语言 代码 · 共 2,323 行 · 第 1/5 页

C
2,323
字号
      xf86XVScreenInit(pScreen, adaptors, num_adaptors);   if (newAdaptors)      xfree(newAdaptors);}static voidI830ResetVideo(ScrnInfoPtr pScrn){   I830Ptr pI830 = I830PTR(pScrn);   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;   I830OverlayRegPtr overlay =	 (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);   DPRINTF(PFX, "I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n",	   pI830->FbBase, pI830->OverlayMem->Start, overlay);   /*    * Default to maximum image size in YV12    */   memset(overlay, 0, sizeof(*overlay));   overlay->YRGB_VPH = 0;   overlay->UV_VPH = 0;   overlay->HORZ_PH = 0;   overlay->INIT_PHS = 0;   overlay->DWINPOS = 0;   overlay->DWINSZ = 0;   overlay->SWIDTH = 0;   overlay->SWIDTHSW = 0;   overlay->SHEIGHT = 0;   overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);   overlay->OCLRC1 = 0x00000080;	/* saturation: bypass */   overlay->AWINPOS = 0;   overlay->AWINSZ = 0;   overlay->FASTHSCALE = 0;   /*    * Enable destination color keying    */   switch (pScrn->depth) {   case 8:      overlay->DCLRKV = 0;      overlay->DCLRKM = 0xffffff | DEST_KEY_ENABLE;      break;   case 15:      overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);      overlay->DCLRKM = 0x070707 | DEST_KEY_ENABLE;      break;   case 16:      overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);      overlay->DCLRKM = 0x070307 | DEST_KEY_ENABLE;      break;   default:      overlay->DCLRKV = pPriv->colorKey;      overlay->DCLRKM = DEST_KEY_ENABLE;      break;   }   overlay->SCLRKVH = 0;   overlay->SCLRKVL = 0;   overlay->SCLRKEN = 0;		/* source color key disable */   overlay->OCONFIG = CC_OUT_8BIT;   /*    * Select which pipe the overlay is enabled on.    */   overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;   if (pPriv->pipe == 0)      overlay->OCONFIG |= OVERLAY_PIPE_A;   else       overlay->OCONFIG |= OVERLAY_PIPE_B;   overlay->OCMD = YUV_420;#if 0   /*     * XXX DUMP REGISTER CODE !!!    * This allows us to dump the complete i845 registers and compare    * with warm boot situations before we upload our first copy.    */   {      int i;      for (i = 0x30000; i < 0x31000; i += 4)	 ErrorF("0x%x 0x%lx\n", i, INREG(i));   }#endif}#define PFIT_CONTROLS 0x61230#define PFIT_AUTOVSCALE_MASK 0x200#define PFIT_ON_MASK 0x80000000#define PFIT_AUTOSCALE_RATIO 0x61238#define PFIT_PROGRAMMED_SCALE_RATIO 0x61234static voidI830SetOneLineModeRatio(ScrnInfoPtr pScrn){   I830Ptr pI830 = I830PTR(pScrn);   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;   CARD32 panelFitControl = INREG(PFIT_CONTROLS);   int vertScale;   pPriv->scaleRatio = 0x10000;   if (panelFitControl & PFIT_ON_MASK) {      if (panelFitControl & PFIT_AUTOVSCALE_MASK) {         vertScale = INREG(PFIT_AUTOSCALE_RATIO) >> 16;      } else {         vertScale = INREG(PFIT_PROGRAMMED_SCALE_RATIO) >> 16;      }      if (vertScale != 0)         pPriv->scaleRatio = ((double) 0x10000 / (double)vertScale) * 0x10000;       pPriv->oneLineMode = TRUE;      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Xvideo one-line mode\n");   }   if (pPriv->scaleRatio == 0x10000)      pPriv->oneLineMode = FALSE;}static voidI830UpdateGamma(ScrnInfoPtr pScrn){   I830Ptr pI830 = I830PTR(pScrn);   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;   OUTREG(OGAMC5, pPriv->gamma5);   OUTREG(OGAMC4, pPriv->gamma4);   OUTREG(OGAMC3, pPriv->gamma3);   OUTREG(OGAMC2, pPriv->gamma2);   OUTREG(OGAMC1, pPriv->gamma1);   OUTREG(OGAMC0, pPriv->gamma0);}static XF86VideoAdaptorPtrI830SetupImageVideo(ScreenPtr pScreen){   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];   I830Ptr pI830 = I830PTR(pScrn);   XF86VideoAdaptorPtr adapt;   I830PortPrivPtr pPriv;   XF86AttributePtr att;   DPRINTF(PFX, "I830SetupImageVideo\n");   if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +			 sizeof(I830PortPrivRec) + sizeof(DevUnion))))      return NULL;   adapt->type = XvWindowMask | XvInputMask | XvImageMask;   adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;   adapt->name = "Intel(R) Video Overlay";   adapt->nEncodings = 1;   adapt->pEncodings = DummyEncoding;   /* update the DummyEncoding for these two chipsets */   if (IS_845G(pI830) || IS_I830(pI830)) {      adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;      adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;   }   adapt->nFormats = NUM_FORMATS;   adapt->pFormats = Formats;   adapt->nPorts = 1;   adapt->pPortPrivates = (DevUnion *) (&adapt[1]);   pPriv = (I830PortPrivPtr) (&adapt->pPortPrivates[1]);   adapt->pPortPrivates[0].ptr = (pointer) (pPriv);   adapt->nAttributes = NUM_ATTRIBUTES;   if (pI830->Clone)      adapt->nAttributes += CLONE_ATTRIBUTES;   if (IS_I9XX(pI830))      adapt->nAttributes += GAMMA_ATTRIBUTES; /* has gamma */   adapt->pAttributes = xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes);   /* Now copy the attributes */   att = adapt->pAttributes;   memcpy((char *)att, (char*)Attributes, sizeof(XF86AttributeRec)* NUM_ATTRIBUTES);   att+=NUM_ATTRIBUTES;   if (pI830->Clone) {      memcpy((char*)att, (char*)CloneAttributes, sizeof(XF86AttributeRec) * CLONE_ATTRIBUTES);      att+=CLONE_ATTRIBUTES;   }   if (IS_I9XX(pI830)) {      memcpy((char*)att, (char*)GammaAttributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);      att+=GAMMA_ATTRIBUTES;   }   adapt->nImages = NUM_IMAGES;   adapt->pImages = Images;   adapt->PutVideo = NULL;   adapt->PutStill = NULL;   adapt->GetVideo = NULL;   adapt->GetStill = NULL;   adapt->StopVideo = I830StopVideo;   adapt->SetPortAttribute = I830SetPortAttribute;   adapt->GetPortAttribute = I830GetPortAttribute;   adapt->QueryBestSize = I830QueryBestSize;   adapt->PutImage = I830PutImage;   adapt->QueryImageAttributes = I830QueryImageAttributes;   pPriv->colorKey = pI830->colorKey & ((1 << pScrn->depth) - 1);   pPriv->videoStatus = 0;   pPriv->brightness = 0;   pPriv->contrast = 64;   pPriv->pipe = pI830->pipe; /* default to current pipe */   pPriv->linear = NULL;   pPriv->currentBuf = 0;   pPriv->gamma5 = 0xc0c0c0;   pPriv->gamma4 = 0x808080;   pPriv->gamma3 = 0x404040;   pPriv->gamma2 = 0x202020;   pPriv->gamma1 = 0x101010;   pPriv->gamma0 = 0x080808;   pPriv->doubleBuffer = 1;   /* gotta uninit this someplace */   REGION_NULL(pScreen, &pPriv->clip);   pI830->adaptor = adapt;   /* With LFP's we need to detect whether we're in One Line Mode, which    * essentially means a resolution greater than 1024x768, and fix up    * the scaler accordingly. */   pPriv->scaleRatio = 0x10000;   pPriv->oneLineMode = FALSE;   /*    * Initialise pPriv->overlayOK.  Set it to TRUE here so that a warning will    * be generated if I830VideoSwitchModeAfter() sets it to FALSE.    */   pPriv->overlayOK = TRUE;   I830VideoSwitchModeAfter(pScrn, pScrn->currentMode);   pI830->BlockHandler = pScreen->BlockHandler;   pScreen->BlockHandler = I830BlockHandler;   xvColorKey = MAKE_ATOM("XV_COLORKEY");   xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");   xvContrast = MAKE_ATOM("XV_CONTRAST");   xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");   /* Allow the pipe to be switched from pipe A to B when in clone mode */   if (pI830->Clone)     xvPipe = MAKE_ATOM("XV_PIPE");      if (IS_I9XX(pI830)) {     xvGamma0 = MAKE_ATOM("XV_GAMMA0");     xvGamma1 = MAKE_ATOM("XV_GAMMA1");     xvGamma2 = MAKE_ATOM("XV_GAMMA2");     xvGamma3 = MAKE_ATOM("XV_GAMMA3");     xvGamma4 = MAKE_ATOM("XV_GAMMA4");     xvGamma5 = MAKE_ATOM("XV_GAMMA5");   }   I830ResetVideo(pScrn);   I830UpdateGamma(pScrn);   return adapt;}static BoolRegionsEqual(RegionPtr A, RegionPtr B){   int *dataA, *dataB;   int num;   num = REGION_NUM_RECTS(A);   if (num != REGION_NUM_RECTS(B))      return FALSE;   if ((A->extents.x1 != B->extents.x1) ||       (A->extents.x2 != B->extents.x2) ||       (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2))      return FALSE;   dataA = (int *)REGION_RECTS(A);   dataB = (int *)REGION_RECTS(B);   while (num--) {      if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))	 return FALSE;      dataA += 2;      dataB += 2;   }   return TRUE;}static voidI830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown){   I830PortPrivPtr pPriv = (I830PortPrivPtr) data;   I830Ptr pI830 = I830PTR(pScrn);   I830OverlayRegPtr overlay =	 (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);   DPRINTF(PFX, "I830StopVideo\n");   REGION_EMPTY(pScrn->pScreen, &pPriv->clip);   if (shutdown) {      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {	 overlay->OCMD &= ~OVERLAY_ENABLE;	 OVERLAY_UPDATE;#if 1	 OVERLAY_OFF;#endif         if (pI830->entityPrivate)            pI830->entityPrivate->XvInUse = -1;      }      if (pPriv->linear) {	 xf86FreeOffscreenLinear(pPriv->linear);	 pPriv->linear = NULL;      }      pPriv->videoStatus = 0;   } else {      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {	 pPriv->videoStatus |= OFF_TIMER;	 pPriv->offTime = currentTime.milliseconds + OFF_DELAY;      }   }}static intI830SetPortAttribute(ScrnInfoPtr pScrn,		     Atom attribute, INT32 value, pointer data){   I830PortPrivPtr pPriv = (I830PortPrivPtr) data;   I830Ptr pI830 = I830PTR(pScrn);   I830OverlayRegPtr overlay =	 (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);   if (attribute == xvBrightness) {      if ((value < -128) || (value > 127))	 return BadValue;      pPriv->brightness = value;      overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);      ErrorF("BRIGHTNESS\n");      overlay->OCMD &= ~OVERLAY_ENABLE;      OVERLAY_UPDATE;#if 1      OVERLAY_OFF;#endif   } else if (attribute == xvContrast) {      if ((value < 0) || (value > 255))	 return BadValue;      pPriv->contrast = value;      overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);      ErrorF("CONTRAST\n");      overlay->OCMD &= ~OVERLAY_ENABLE;      OVERLAY_UPDATE;#if 1      OVERLAY_OFF;#endif   } else if (pI830->Clone && attribute == xvPipe) {      if ((value < 0) || (value > 1))         return BadValue;      pPriv->pipe = value;      /*       * Select which pipe the overlay is enabled on.       */      overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;      if (pPriv->pipe == 0)         overlay->OCONFIG |= OVERLAY_PIPE_A;      else          overlay->OCONFIG |= OVERLAY_PIPE_B;      ErrorF("PIPE CHANGE\n");      overlay->OCMD &= ~OVERLAY_ENABLE;      OVERLAY_UPDATE;#if 1      OVERLAY_OFF;#endif   } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {      pPriv->gamma0 = value;       if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)         pPriv->gamma1 = pPriv->gamma0 + 0x7d;   } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {      pPriv->gamma1 = value;      if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)        pPriv->gamma0 = pPriv->gamma1 - 0x7d;   } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {      pPriv->gamma2 = value;      if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)         pPriv->gamma3 = pPriv->gamma2 + 0x7d;   } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) {      pPriv->gamma3 = value;      if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)         pPriv->gamma2 = pPriv->gamma3 - 0x7d;   } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) {      pPriv->gamma4 = value;      if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)         pPriv->gamma5 = pPriv->gamma4 + 0x7d;   } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) {      pPriv->gamma5 = value;      if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)         pPriv->gamma4 = pPriv->gamma5 - 0x7d;   } else if (attribute == xvColorKey) {      pPriv->colorKey = value;      switch (pScrn->depth) {      case 16:	 overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);	 break;      case 15:	 overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);	 break;      default:	 overlay->DCLRKV = pPriv->colorKey;	 break;      }      ErrorF("COLORKEY\n");      overlay->OCMD &= ~OVERLAY_ENABLE;      OVERLAY_UPDATE;#if 1      OVERLAY_OFF;#endif      REGION_EMPTY(pScrn->pScreen, &pPriv->clip);   } else if(attribute == xvDoubleBuffer) {      if ((value < 0) || (value > 1))         return BadValue;      /* Do not allow buffer change while playing video */      if(!*pI830->overlayOn)     	 pPriv->doubleBuffer = value;   } else      return BadMatch;   /* We've already confirmed that the overlay is off, ready for updating */   if ((attribute == xvGamma0 ||        attribute == xvGamma1 ||        attribute == xvGamma2 ||        attribute == xvGamma3 ||        attribute == xvGamma4 ||        attribute == xvGamma5) && (IS_I9XX(pI830))) {        ErrorF("GAMMA\n");        overlay->OCMD &= ~OVERLAY_ENABLE;        OVERLAY_UPDATE;#if 1        OVERLAY_OFF;#endif	I830UpdateGamma(pScrn);   }   return Success;}static intI830GetPortAttribute(ScrnInfoPtr pScrn,		     Atom attribute, INT32 * value, pointer data){   I830Ptr pI830 = I830PTR(pScrn);   I830PortPrivPtr pPriv = (I830PortPrivPtr) data;   if (attribute == xvBrightness) {      *value = pPriv->brightness;   } else if (attribute == xvContrast) {      *value = pPriv->contrast;   } else if (pI830->Clone && attribute == xvPipe) {      *value = pPriv->pipe;   } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {      *value = pPriv->gamma0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?