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