i830_video.c
来自「是由intel提供的针对intel显卡915以上系列的linux驱动」· C语言 代码 · 共 2,323 行 · 第 1/5 页
C
2,323 行
return new_linear;}static intI830PutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, unsigned char *buf, short width, short height, Bool sync, RegionPtr clipBoxes, pointer data){ I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = (I830PortPrivPtr) data; ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; I830OverlayRegPtr overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); INT32 x1, x2, y1, y2; int srcPitch, srcPitch2 = 0, dstPitch; int top, left, npixels, nlines, size, loops; BoxRec dstBox; DPRINTF(PFX, "I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n" "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height); if (pI830->entityPrivate) { if (pI830->entityPrivate->XvInUse != -1 && pI830->entityPrivate->XvInUse != pPriv->pipe) {#ifdef PANORAMIX if (!noPanoramiXExtension) { return Success; /* faked for trying to share it */ } else#endif { return BadAlloc; } } pI830->entityPrivate->XvInUse = pPriv->pipe; } /* overlay limits */ if(src_w > (drw_w * 7)) drw_w = src_w * 7; if(src_h > (drw_h * 7)) drw_h = src_h * 7; /* Clip */ x1 = src_x; x2 = src_x + src_w; y1 = src_y; y2 = src_y + src_h; dstBox.x1 = drw_x; dstBox.x2 = drw_x + drw_w; dstBox.y1 = drw_y; dstBox.y2 = drw_y + drw_h; if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height)) return Success; switch (id) { case FOURCC_YV12: case FOURCC_I420: srcPitch = (width + 3) & ~3; srcPitch2 = ((width >> 1) + 3) & ~3;#if 1 if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height / 2) + 63) & ~63; size = dstPitch * width * 3; } else { dstPitch = ((width / 2) + 63) & ~63; /* of chroma */ size = dstPitch * height * 3; }#else if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height / 2) + 511) & ~511; size = dstPitch * width * 3; } else { dstPitch = ((width / 2) + 511) & ~511; /* of chroma */ size = dstPitch * height * 3; }#endif break; case FOURCC_UYVY: case FOURCC_YUY2: default: srcPitch = width << 1;#if 1 if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height << 1) + 63) & ~63; size = dstPitch * width; } else { dstPitch = ((width << 1) + 63) & ~63; /* of chroma */ size = dstPitch * height; }#else if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height << 1) + 511) & ~511; size = dstPitch * width; } else { dstPitch = ((width << 1) + 511) & ~511; /* of chroma */ size = dstPitch * height; }#endif break; } ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size); /* size is multiplied by 2 because we have two buffers that are flipping */ pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear, (pPriv->doubleBuffer ? size * 2 : size) / pI830->cpp); if(!pPriv->linear || pPriv->linear->offset < (pScrn->virtualX * pScrn->virtualY)) return BadAlloc; /* fixup pointers */#if 0 pPriv->YBuf0offset = pScrn->fbOffset + pPriv->linear->offset * pI830->cpp;#else pPriv->YBuf0offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp;#endif if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); if(pPriv->doubleBuffer) { pPriv->YBuf1offset = pPriv->YBuf0offset + size; pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width); pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2); } } else { pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2); if(pPriv->doubleBuffer) { pPriv->YBuf1offset = pPriv->YBuf0offset + size; pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2); } } /* Make sure this buffer isn't in use */ loops = 0; if (*pI830->overlayOn && pPriv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) { while (loops < 1000000) {#if USE_USLEEP_FOR_VIDEO usleep(10);#endif if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) { break; } loops++; } if (loops >= 1000000) { ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf);#if 0 pPriv->currentBuf = !pPriv->currentBuf;#endif } /* buffer swap */ if (pPriv->currentBuf == 0) pPriv->currentBuf = 1; else pPriv->currentBuf = 0; } /* copy data */ top = y1 >> 16; left = (x1 >> 16) & ~1; npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; switch (id) { case FOURCC_YV12: case FOURCC_I420: top &= ~1; nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; I830CopyPlanarData(pScrn, buf, srcPitch, srcPitch2, dstPitch, height, top, left, nlines, npixels, id); break; case FOURCC_UYVY: case FOURCC_YUY2: default: nlines = ((y2 + 0xffff) >> 16) - top; I830CopyPackedData(pScrn, buf, srcPitch, dstPitch, top, left, nlines, npixels); break; } /* update cliplist */ if (!RegionsEqual(&pPriv->clip, clipBoxes)) { REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes); } I830DisplayVideo(pScrn, id, width, height, dstPitch, x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); pPriv->videoStatus = CLIENT_VIDEO_ON; return Success;}static intI830QueryImageAttributes(ScrnInfoPtr pScrn, int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets){ I830Ptr pI830 = I830PTR(pScrn); int size, tmp; ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h); if (IS_845G(pI830) || IS_I830(pI830)) { if (*w > IMAGE_MAX_WIDTH_LEGACY) *w = IMAGE_MAX_WIDTH_LEGACY; if (*h > IMAGE_MAX_HEIGHT_LEGACY) *h = IMAGE_MAX_HEIGHT_LEGACY; } else { if (*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; if (*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; } *w = (*w + 1) & ~1; if (offsets) offsets[0] = 0; switch (id) { /* IA44 is for XvMC only */ case FOURCC_IA44: case FOURCC_AI44: if (pitches) pitches[0] = *w; size = *w * *h; break; case FOURCC_YV12: case FOURCC_I420: *h = (*h + 1) & ~1; size = (*w + 3) & ~3; if (pitches) pitches[0] = size; size *= *h; if (offsets) offsets[1] = size; tmp = ((*w >> 1) + 3) & ~3; if (pitches) pitches[1] = pitches[2] = tmp; tmp *= (*h >> 1); size += tmp; if (offsets) offsets[2] = size; size += tmp; if (pitches) ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n", pitches[0], pitches[1], pitches[2]); if (offsets) ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1], offsets[2]); if (offsets) ErrorF("size is %d\n", size); break; case FOURCC_UYVY: case FOURCC_YUY2: default: size = *w << 1; if (pitches) pitches[0] = size; size *= *h; break; } return size;}static voidI830BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask){ ScreenPtr pScreen = screenInfo.screens[i]; ScrnInfoPtr pScrn = xf86Screens[i]; I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); I830OverlayRegPtr overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); pScreen->BlockHandler = pI830->BlockHandler; (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); pScreen->BlockHandler = I830BlockHandler; if (pPriv->videoStatus & TIMER_MASK) {#if 1 Time now = currentTime.milliseconds;#else UpdateCurrentTime();#endif if (pPriv->videoStatus & OFF_TIMER) { if (pPriv->offTime < now) { /* Turn off the overlay */ ErrorF("BLOCKHANDLER\n"); overlay->OCMD &= ~OVERLAY_ENABLE; OVERLAY_UPDATE;#if 1 OVERLAY_OFF;#endif pPriv->videoStatus = FREE_TIMER; pPriv->freeTime = now + FREE_DELAY; if (pI830->entityPrivate) pI830->entityPrivate->XvInUse = -1; } } else { /* FREE_TIMER */ if (pPriv->freeTime < now) { if (pPriv->linear) { xf86FreeOffscreenLinear(pPriv->linear); pPriv->linear = NULL; } pPriv->videoStatus = 0; } } }}/*************************************************************************** * Offscreen Images ***************************************************************************/typedef struct { FBLinearPtr linear; Bool isOn;} OffscreenPrivRec, *OffscreenPrivPtr;static intI830AllocateSurface(ScrnInfoPtr pScrn, int id, unsigned short w, unsigned short h, XF86SurfacePtr surface){ FBLinearPtr linear; int pitch, fbpitch, size, bpp; OffscreenPrivPtr pPriv; I830Ptr pI830 = I830PTR(pScrn); ErrorF("I830AllocateSurface\n"); if (IS_845G(pI830) || IS_I830(pI830)) { if ((w > IMAGE_MAX_WIDTH_LEGACY) || (h > IMAGE_MAX_HEIGHT_LEGACY)) return BadAlloc; } else { if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) return BadAlloc; } /* What to do when rotated ?? */ if (pI830->rotation != RR_Rotate_0) return BadAlloc; w = (w + 1) & ~1; pitch = ((w << 1) + 15) & ~15; bpp = pScrn->bitsPerPixel >> 3; fbpitch = bpp * pScrn->displayWidth; size = ((pitch * h) + bpp - 1) / bpp; if (!(linear = I830AllocateMemory(pScrn, NULL, size))) return BadAlloc; surface->width = w; surface->height = h; if (!(surface->pitches = xalloc(sizeof(int)))) { xf86FreeOffscreenLinear(linear); return BadAlloc; } if (!(surface->offsets = xalloc(sizeof(int)))) { xfree(surface->pitches); xf86FreeOffscreenLinear(linear); return BadAlloc; } if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { xfree(surface->pitches); xfree(surface->offsets); xf86FreeOffscreenLinear(linear); return BadAlloc; } pPriv->linear = linear; pPriv->isOn = FALSE; surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; surface->offsets[0] = linear->offset * bpp; surface->devPrivate.ptr = (pointer) pPriv;#if 0 memset(pI830->FbBase + pScrn->fbOffset + surface->offsets[0], 0, size);#else memset(pI830->FbBase + pI830->FrontBuffer.Start + surface->offsets[0], 0, size);#endif return Success;}static intI830StopSurface(XF86SurfacePtr surface){ OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; ScrnInfoPtr pScrn = surface->pScrn; if (pPriv->isOn) { I830Ptr pI830 = I830PTR(pScrn); I830OverlayRegPtr overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); ErrorF("StopSurface\n"); overlay->OCMD &= ~OVERLAY_ENABLE; OVERLAY_UPDATE;#if 1 OVERLAY_OFF;#endif if (pI830->entityPrivate) pI830->entityPrivate->XvInUse = -1; pPriv->isOn = FALSE; } return Success;}static intI830FreeSurface(XF86SurfacePtr surface){ OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; if (pPriv->isOn) { I830StopSurface(surface); } xf86FreeOffscreenLinear(pPriv->linear); xfree(surface->pitches); xfree(surface->offsets); xfree(surface->devPrivate.ptr); return Success;}static intI830GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 * value){ return I830GetPortAttribute(pScrn, attribute, value, 0);}static intI830SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?