i830_video.c
来自「是由intel提供的针对intel显卡915以上系列的linux驱动」· C语言 代码 · 共 2,323 行 · 第 1/5 页
C
2,323 行
switch (pI830->rotation) { case RR_Rotate_0: dstBox->x1 -= pScrn->frameX0; dstBox->x2 -= pScrn->frameX0; dstBox->y1 -= pScrn->frameY0; dstBox->y2 -= pScrn->frameY0; break; case RR_Rotate_90: tmp = dstBox->x1; dstBox->x1 = dstBox->y1 - pScrn->frameX0; dstBox->y1 = pScrn->virtualY - tmp - pScrn->frameY0; tmp = dstBox->x2; dstBox->x2 = dstBox->y2 - pScrn->frameX0; dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0; tmp = dstBox->y1; dstBox->y1 = dstBox->y2; dstBox->y2 = tmp; break; case RR_Rotate_180: tmp = dstBox->x1; dstBox->x1 = pScrn->virtualX - dstBox->x2 - pScrn->frameX0; dstBox->x2 = pScrn->virtualX - tmp - pScrn->frameX0; tmp = dstBox->y1; dstBox->y1 = pScrn->virtualY - dstBox->y2 - pScrn->frameY0; dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0; break; case RR_Rotate_270: tmp = dstBox->x1; dstBox->x1 = pScrn->virtualX - dstBox->y1 - pScrn->frameX0; dstBox->y1 = tmp - pScrn->frameY0; tmp = dstBox->x2; dstBox->x2 = pScrn->virtualX - dstBox->y2 - pScrn->frameX0; dstBox->y2 = tmp - pScrn->frameY0; tmp = dstBox->x1; dstBox->x1 = dstBox->x2; dstBox->x2 = tmp; break; } /* Fix up the dstBox if outside the visible screen */ { int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0; int offset_y = (dstBox->y1 < 0) ? -dstBox->y1 : 0; int offset, offset2; /* align */ offset_x = (offset_x + 3) & ~3; offset_y = (offset_y + 3) & ~3; if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { height -= offset_x; width -= offset_y; } else { height -= offset_y; width -= offset_x; } if (id == FOURCC_I420 || id == FOURCC_YV12) { offset = ((offset_x/2) + (dstPitch * offset_y)) * 2; offset2 = ((offset_x/2) + ((dstPitch/2) * offset_y)); } else { offset = ((offset_x*2) + (dstPitch * offset_y)); offset2 = ((offset_x*2) + ((dstPitch/2) * offset_y)); } /* buffer locations */ pPriv->YBuf0offset += offset; pPriv->UBuf0offset += offset2; pPriv->VBuf0offset += offset2; if(pPriv->doubleBuffer) { pPriv->YBuf1offset += offset; pPriv->UBuf1offset += offset2; pPriv->VBuf1offset += offset2; } } if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { tmp = width; width = height; height = tmp; tmp = drw_w; drw_w = drw_h; drw_h = tmp; tmp = src_w; src_w = src_h; src_h = tmp; } if (pPriv->oneLineMode) { /* change the coordinates with panel fitting active */ dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1; dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1; /* Now, alter the height, so we scale to the correct size */ drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1; } { /* Keep the engine happy and clip to the real vertical size just * in case an LFP is in use and it's not at it's native resolution. */ int vactive = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF); vactive += 1; if (dstBox->y1 < 0) dstBox->y1 = 0; if (dstBox->y2 < 0) dstBox->y2 = 0; if (dstBox->x1 < 0) dstBox->x1 = 0; if (dstBox->x2 < 0) dstBox->x2 = 0; if (dstBox->y1 > vactive) dstBox->y1 = vactive; if (dstBox->y2 > vactive) dstBox->y2 = vactive; if (dstBox->x1 > pScrn->currentMode->HDisplay) dstBox->x1 = pScrn->currentMode->HDisplay - 1; if (dstBox->x2 > pScrn->currentMode->HDisplay) dstBox->x2 = pScrn->currentMode->HDisplay - 1; /* nothing do to */ if ((!dstBox->x1 && !dstBox->x2) || (!dstBox->y1 && !dstBox->y2)) { ErrorF("NOTHING TO DO\n"); return; } if ((dstBox->x1 == (pScrn->currentMode->HDisplay - 1) && dstBox->x2 == (pScrn->currentMode->HDisplay - 1)) || (dstBox->y1 == vactive && dstBox->y2 == vactive)) { ErrorF("NOTHING TO DO\n"); return; } if ((dstBox->y2 - dstBox->y1) <= N_VERT_Y_TAPS) { ErrorF("NOTHING TO DO\n"); return; } if ((dstBox->x2 - dstBox->x1) <= 2) { ErrorF("NOTHING TO DO\n"); return; } } if (IS_I9XX(pI830)) { shift = 6; mask = 0x3f; } else { shift = 5; mask = 0x1f; } if (pPriv->currentBuf == 0) { offsety = pPriv->YBuf0offset; offsetu = pPriv->UBuf0offset; } else { offsety = pPriv->YBuf1offset; offsetu = pPriv->UBuf1offset; } switch (id) { case FOURCC_YV12: case FOURCC_I420: swidth = width; overlay->SWIDTH = swidth; swidth /= 2; overlay->SWIDTH |= (swidth & 0x7ff) << 16; swidth = ((offsety + width + mask) >> shift) - (offsety >> shift); if (IS_I9XX(pI830)) swidth <<= 1; swidth -= 1; ErrorF("Y width is %d, swidth is %d\n", width, swidth); overlay->SWIDTHSW = swidth << 2; swidth = ((offsetu + (width / 2) + mask) >> shift) - (offsetu >> shift); if (IS_I9XX(pI830)) swidth <<= 1; swidth -= 1; ErrorF("UV width is %d, swidthsw is %d\n", width / 2, swidth); overlay->SWIDTHSW |= swidth << 18; ErrorF("HEIGHT is %d\n",height); overlay->SHEIGHT = height | ((height / 2) << 16); break; case FOURCC_UYVY: case FOURCC_YUY2: default: swidth = width; overlay->SWIDTH = swidth; ErrorF("Y width is %d\n", swidth); swidth = ((offsety + (width << 1) + mask) >> shift) - (offsety >> shift); if (IS_I9XX(pI830)) swidth <<= 1; swidth -= 1; ErrorF("swidthsw is %d\n", swidth); overlay->SWIDTHSW = swidth << 2; ErrorF("HEIGHT is %d\n",height); overlay->SHEIGHT = height; break; } overlay->OCMD = OVERLAY_ENABLE; overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1; overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) | (dstBox->x2 - dstBox->x1); ErrorF("dstBox: x1: %d, y1: %d, x2: %d, y2: %d\n", dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2); /* buffer locations */ overlay->OBUF_0Y = pPriv->YBuf0offset; overlay->OBUF_0U = pPriv->UBuf0offset; overlay->OBUF_0V = pPriv->VBuf0offset; if(pPriv->doubleBuffer) { overlay->OBUF_1Y = pPriv->YBuf1offset; overlay->OBUF_1U = pPriv->UBuf1offset; overlay->OBUF_1V = pPriv->VBuf1offset; } ErrorF("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n", overlay->OBUF_0Y, overlay->OBUF_0U, overlay->OBUF_0V); ErrorF("Buffers: Y1: 0x%lx, U1: 0x%lx, V1: 0x%lx\n", overlay->OBUF_1Y, overlay->OBUF_1U, overlay->OBUF_1V);#if 0 { int i; ErrorF("First 32 bytes of Y data:\n"); for (i = 0; i < 32; i++) ErrorF(" %02x", ((unsigned char *)pI830->FbBase + pPriv->YBuf0offset)[i]); ErrorF("\n"); ErrorF("First 16 bytes of U data:\n"); for (i = 0; i < 16; i++) ErrorF(" %02x", ((unsigned char *)pI830->FbBase + pPriv->UBuf0offset)[i]); ErrorF("\n"); ErrorF("First 16 bytes of V data:\n"); for (i = 0; i < 16; i++) ErrorF(" %02x", ((unsigned char *)pI830->FbBase + pPriv->VBuf0offset)[i]); ErrorF("\n"); }#endif ErrorF("pos: 0x%lx, size: 0x%lx\n", overlay->DWINPOS, overlay->DWINSZ); ErrorF("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h); /* * Calculate horizontal and vertical scaling factors and polyphase * coefficients. */ { Bool scaleChanged = FALSE; int xscaleInt, xscaleFract, yscaleInt, yscaleFract; int xscaleIntUV, xscaleFractUV; int yscaleIntUV, yscaleFractUV; /* UV is half the size of Y -- YUV420 */ int uvratio = 2; CARD32 newval; coeffRec xcoeffY[N_HORIZ_Y_TAPS * N_PHASES]; coeffRec xcoeffUV[N_HORIZ_UV_TAPS * N_PHASES]; int i, j, pos; /* * Y down-scale factor as a multiple of 4096. */ xscaleFract = ((src_w - 1) << 12) / drw_w; yscaleFract = ((src_h - 1) << 12) / drw_h; /* Calculate the UV scaling factor. */ xscaleFractUV = xscaleFract / uvratio; yscaleFractUV = yscaleFract / uvratio; /* * To keep the relative Y and UV ratios exact, round the Y scales * to a multiple of the Y/UV ratio. */ xscaleFract = xscaleFractUV * uvratio; yscaleFract = yscaleFractUV * uvratio; /* Integer (un-multiplied) values. */ xscaleInt = xscaleFract >> 12; yscaleInt = yscaleFract >> 12; xscaleIntUV = xscaleFractUV >> 12; yscaleIntUV = yscaleFractUV >> 12; ErrorF("xscale: %x.%03x, yscale: %x.%03x\n", xscaleInt, xscaleFract & 0xFFF, yscaleInt, yscaleFract & 0xFFF); ErrorF("UV xscale: %x.%03x, UV yscale: %x.%03x\n", xscaleIntUV, xscaleFractUV & 0xFFF, yscaleIntUV, yscaleFractUV & 0xFFF); /* shouldn't get here */ if (xscaleInt > 7) { ErrorF("xscale: bad scale\n"); return; } /* shouldn't get here */ if (xscaleIntUV > 7) { ErrorF("xscaleUV: bad scale\n"); return; } newval = (xscaleInt << 16) | ((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20); if (newval != overlay->YRGBSCALE) { scaleChanged = TRUE; overlay->YRGBSCALE = newval; } newval = (xscaleIntUV << 16) | ((xscaleFractUV & 0xFFF) << 3) | ((yscaleFractUV & 0xFFF) << 20); if (newval != overlay->UVSCALE) { scaleChanged = TRUE; overlay->UVSCALE = newval; } newval = yscaleInt << 16 | yscaleIntUV; if (newval != overlay->UVSCALEV) { scaleChanged = TRUE; overlay->UVSCALEV = newval; } /* Recalculate coefficients if the scaling changed. */ /* * Only Horizontal coefficients so far. */ if (scaleChanged) { double fCutoffY; double fCutoffUV; fCutoffY = xscaleFract / 4096.0; fCutoffUV = xscaleFractUV / 4096.0; /* Limit to between 1.0 and 3.0. */ if (fCutoffY < MIN_CUTOFF_FREQ) fCutoffY = MIN_CUTOFF_FREQ; if (fCutoffY > MAX_CUTOFF_FREQ) fCutoffY = MAX_CUTOFF_FREQ; if (fCutoffUV < MIN_CUTOFF_FREQ) fCutoffUV = MIN_CUTOFF_FREQ; if (fCutoffUV > MAX_CUTOFF_FREQ) fCutoffUV = MAX_CUTOFF_FREQ; UpdateCoeff(N_HORIZ_Y_TAPS, fCutoffY, TRUE, TRUE, xcoeffY); UpdateCoeff(N_HORIZ_UV_TAPS, fCutoffUV, TRUE, FALSE, xcoeffUV); for (i = 0; i < N_PHASES; i++) { for (j = 0; j < N_HORIZ_Y_TAPS; j++) { pos = i * N_HORIZ_Y_TAPS + j; overlay->Y_HCOEFS[pos] = xcoeffY[pos].sign << 15 | xcoeffY[pos].exponent << 12 | xcoeffY[pos].mantissa; } } for (i = 0; i < N_PHASES; i++) { for (j = 0; j < N_HORIZ_UV_TAPS; j++) { pos = i * N_HORIZ_UV_TAPS + j; overlay->UV_HCOEFS[pos] = xcoeffUV[pos].sign << 15 | xcoeffUV[pos].exponent << 12 | xcoeffUV[pos].mantissa; } } } } switch (id) { case FOURCC_YV12: case FOURCC_I420: ErrorF("YUV420\n");#if 0 /* set UV vertical phase to -0.25 */ overlay->UV_VPH = 0x30003000;#endif ErrorF("UV stride is %d, Y stride is %d\n", dstPitch, dstPitch * 2); overlay->OSTRIDE = (dstPitch * 2) | (dstPitch << 16); overlay->OCMD &= ~SOURCE_FORMAT; overlay->OCMD &= ~OV_BYTE_ORDER; overlay->OCMD |= YUV_420; break; case FOURCC_UYVY: case FOURCC_YUY2: default: ErrorF("YUV422\n"); overlay->OSTRIDE = dstPitch; overlay->OCMD &= ~SOURCE_FORMAT; overlay->OCMD |= YUV_422; overlay->OCMD &= ~OV_BYTE_ORDER; if (id == FOURCC_UYVY) overlay->OCMD |= Y_SWAP; break; } overlay->OCMD &= ~(BUFFER_SELECT | FIELD_SELECT); if (pPriv->currentBuf == 0) overlay->OCMD |= BUFFER0; else overlay->OCMD |= BUFFER1; ErrorF("OCMD is 0x%lx\n", overlay->OCMD); OVERLAY_UPDATE;}static FBLinearPtrI830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size){ ScreenPtr pScreen; FBLinearPtr new_linear = NULL; DPRINTF(PFX, "I830AllocateMemory\n"); if (linear) { if (linear->size >= size) return linear; if (xf86ResizeOffscreenLinear(linear, size)) return linear; xf86FreeOffscreenLinear(linear); } pScreen = screenInfo.screens[pScrn->scrnIndex]; new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, NULL, NULL, NULL); if (!new_linear) { int max_size; xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, PRIORITY_EXTREME); if (max_size < size) { ErrorF("No memory available\n"); return NULL; } xf86PurgeUnlockedOffscreenAreas(pScreen); new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, NULL, NULL, NULL); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?