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 + -
显示快捷键?