⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i810xvmc.c

📁 显驱动 Intel英特尔G45G43G41G35G33G31G965Q963Q965GM965系列显卡最新X.Org驱动2.4.0版For Linux
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************Copyright 2001 Intel Corporation.  All Rights Reserved.Permission is hereby granted, free of charge, to any person obtaining acopy of this software and associated documentation files (the"Software"), to deal in the Software without restriction, includingwithout limitation the rights to use, copy, modify, merge, publish,distribute, sub license, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so, subject tothe following conditions:The above copyright notice and this permission notice (including thenext paragraph) shall be included in all copies or substantial portionsof the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OROTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE ORTHE USE OR OTHER DEALINGS IN THE SOFTWARE.**************************************************************************//*************************************************************************** File libI810XvMC.c**** Authors:**      Matt Sottek <matthew.j.sottek@intel.com>**      Bob Paauwe  <bob.j.paauwe@intel.com>*******************************************************************************//* $XFree86: xc/lib/XvMC/hw/i810/I810XvMC.c,v 1.10 2002/10/30 12:52:01 alanh Exp $ */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <signal.h>#include <fcntl.h>#include <dirent.h>#include <string.h>#include <sys/ioctl.h>#include <X11/Xlibint.h>#include <fourcc.h>#include <X11/extensions/Xv.h>#include <X11/extensions/Xvlib.h>#include <X11/extensions/XvMC.h>#include <X11/extensions/XvMClib.h>#include "I810XvMC.h"static int error_base;static int event_base;/***************************************************************************// Function: i810_get_free_buffer// Description: Allocates a free dma page using kernel ioctls, then//   programs the data into the already allocated dma buffer list.// Arguments: pI810XvMC private data structure from the current context.// Notes: We faked the drmMapBufs for the i810's security so now we have//   to insert an allocated page into the correct spot in the faked//   list to keep up appearences.//   Concept for this function was taken from Mesa sources.// Returns: drmBufPtr containing the information about the allocated page.***************************************************************************/drmBufPtr i810_get_free_buffer(i810XvMCContext *pI810XvMC) {   drmI810DMA dma;   drmBufPtr buf;   dma.granted = 0;   dma.request_size = 4096;   while(!dma.granted) {     if(GET_BUFFER(pI810XvMC, dma) || !dma.granted)       FLUSH(pI810XvMC);   } /* No DMA granted */   buf = &(pI810XvMC->dmabufs->list[dma.request_idx]);   buf->idx = dma.request_idx;   buf->used = 0;   buf->total = dma.request_size;   buf->address = (drmAddress)dma.virtual;   return buf;}/***************************************************************************// Function: free_privContext// Description: Free's the private context structure if the reference//  count is 0.***************************************************************************/void i810_free_privContext(i810XvMCContext *pI810XvMC) {  I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);  pI810XvMC->ref--;  if(!pI810XvMC->ref) {    drmUnmapBufs(pI810XvMC->dmabufs);    drmUnmap(pI810XvMC->overlay.address,pI810XvMC->overlay.size);    drmUnmap(pI810XvMC->surfaces.address,pI810XvMC->surfaces.size);    drmClose(pI810XvMC->fd);    free(pI810XvMC->dmabufs->list);    free(pI810XvMC);  }  I810_UNLOCK(pI810XvMC);}/***************************************************************************// Function: XvMCCreateContext// Description: Create a XvMC context for the given surface parameters.// Arguments://   display - Connection to the X server.//   port - XvPortID to use as avertised by the X connection.//   surface_type_id - Unique identifier for the Surface type.//   width - Width of the surfaces.//   height - Height of the surfaces.//   flags - one or more of the following//      XVMC_DIRECT - A direct rendered context is requested.//// Notes: surface_type_id and width/height parameters must match those//        returned by XvMCListSurfaceTypes.// Returns: Status***************************************************************************/Status XvMCCreateContext(Display *display, XvPortID port,			 int surface_type_id, int width, int height, int flags,			 XvMCContext *context) {    i810XvMCContext *pI810XvMC;  int priv_count;  uint *priv_data;  uint magic;  Status ret;  int major, minor;  /* Verify Obvious things first */  if(context == NULL) {    return XvMCBadContext;  }  if(!(flags & XVMC_DIRECT)) {    /* Indirect */    printf("Indirect Rendering not supported!\nUsing Direct.");  }  /* Limit use to root for now */  if(geteuid()) {    printf("Use of XvMC on i810 is currently limited to root\n");    return BadAccess;  }  /* FIXME: Check $DISPLAY for legal values here */  context->surface_type_id = surface_type_id;  context->width = (unsigned short)width;  context->height = (unsigned short)height;  context->flags = flags;  context->port = port;  /*      Width, Height, and flags are checked against surface_type_id     and port for validity inside the X server, no need to check     here.  */  /* Allocate private Context data */  context->privData = (void *)malloc(sizeof(i810XvMCContext));  if(!context->privData) {    printf("Unable to allocate resources for XvMC context.\n");    return BadAlloc;  }  pI810XvMC = (i810XvMCContext *)context->privData;  /* Verify the XvMC extension exists */  if(! XvMCQueryExtension(display, &event_base,			  &error_base)) {    printf("XvMC Extension is not available!\n");    return BadAlloc;  }  /* Verify XvMC version */  ret = XvMCQueryVersion(display, &major, &minor);  if(ret) {    printf("XvMCQuery Version Failed, unable to determine protocol version\n");  }  /* FIXME: Check Major and Minor here */  /* Check for drm */  if(! drmAvailable()) {    printf("Direct Rendering is not avilable on this system!\n");    return BadAlloc;  }  /*      Build the Attribute Atoms, and Initialize the ones that exist     in Xv.  */  pI810XvMC->xv_colorkey = XInternAtom(display,"XV_COLORKEY",0);  if(!pI810XvMC->xv_colorkey) {    return XvBadPort;  }  ret = XvGetPortAttribute(display,port,pI810XvMC->xv_colorkey,			   &pI810XvMC->colorkey);  if(ret) {    return ret;  }  pI810XvMC->xv_brightness = XInternAtom(display,"XV_BRIGHTNESS",0);  pI810XvMC->xv_saturation = XInternAtom(display,"XV_SATURATION",0);  pI810XvMC->xv_contrast = XInternAtom(display,"XV_CONTRAST",0);  pI810XvMC->brightness = 0;  pI810XvMC->saturation = 0x80;  /* 1.0 in 3.7 format */  pI810XvMC->contrast = 0x40; /* 1.0 in 3.6 format */  /* Open DRI Device */  if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) {    printf("DRM Device for i810 could not be opened.\n");    free(pI810XvMC);    return BadAccess;  } /* !pI810XvMC->fd */  /* Get magic number and put it in privData for passing */  drmGetMagic(pI810XvMC->fd,&magic);  context->flags = (unsigned long)magic;  /*    Pass control to the X server to create a drm_context_t for us and    validate the with/height and flags.  */  if((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {    printf("Unable to create XvMC Context.\n");    return ret;  }  /*      X server returns a structure like this:     drm_context_t     fbBase     OverlayOffset     OverlaySize     SurfacesOffset     SurfacesSize     busIdString = 9 char + 1  */  if(priv_count != 9) {    printf("_xvmc_create_context() returned incorrect data size!\n");    printf("\tExpected 9, got %d\n",priv_count);    _xvmc_destroy_context(display, context);    free(pI810XvMC);    return BadAlloc;  }  pI810XvMC->drmcontext = priv_data[0];  pI810XvMC->fb_base = priv_data[1];  pI810XvMC->overlay.offset = priv_data[2] + priv_data[1];  pI810XvMC->overlay.size = priv_data[3];  pI810XvMC->surfaces.offset = priv_data[4] + priv_data[1];  pI810XvMC->surfaces.size = priv_data[5];  strncpy(pI810XvMC->busIdString,(char *)&priv_data[6],9);  pI810XvMC->busIdString[9] = '\0';  /* Must free the private data we were passed from X */  free(priv_data);    /* Initialize private context values */  pI810XvMC->current = 0;  pI810XvMC->lock = 0;  pI810XvMC->last_flip = 0;  pI810XvMC->dual_prime = 0;  /*      Map dma Buffers: Not really, this would be a drmMapBufs     but due to the i810 security model we have to just create an     empty data structure to fake it.  */  pI810XvMC->dmabufs = (drmBufMapPtr)malloc(sizeof(drmBufMap));  if(pI810XvMC->dmabufs == NULL) {    printf("Dma Bufs could not be mapped.\n");    _xvmc_destroy_context(display, context);    free(pI810XvMC);    return BadAlloc;  } /* pI810XvMC->dmabufs == NULL */  memset(pI810XvMC->dmabufs, 0, sizeof(drmBufMap));  pI810XvMC->dmabufs->list = (drmBufPtr)malloc(sizeof(drmBuf) *					       I810_DMA_BUF_NR);  if(pI810XvMC->dmabufs->list == NULL) {    printf("Dma Bufs could not be mapped.\n");    _xvmc_destroy_context(display, context);    free(pI810XvMC);    return BadAlloc;  } /* pI810XvMC->dmabufs->list == NULL */  memset(pI810XvMC->dmabufs->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR);    /* Map the Overlay memory */  if(drmMap(pI810XvMC->fd,pI810XvMC->overlay.offset,	    pI810XvMC->overlay.size,&(pI810XvMC->overlay.address)) < 0) {    printf("Unable to map Overlay at offset 0x%x and size 0x%x\n",	   (unsigned int)pI810XvMC->overlay.offset,pI810XvMC->overlay.size);    _xvmc_destroy_context(display, context);    free(pI810XvMC->dmabufs->list);    free(pI810XvMC);    return BadAlloc;  } /* drmMap() < 0 */    /* Overlay Regs are offset 1024 into Overlay Map */  pI810XvMC->oregs = (i810OverlayRec *)    ((unsigned char *)pI810XvMC->overlay.address + 1024);  /* Map Surfaces */  if(drmMap(pI810XvMC->fd,pI810XvMC->surfaces.offset,	    pI810XvMC->surfaces.size,&(pI810XvMC->surfaces.address)) < 0) {    printf("Unable to map XvMC Surfaces.\n");    _xvmc_destroy_context(display, context);    free(pI810XvMC->dmabufs->list);    free(pI810XvMC);    return BadAlloc;  } /* drmMap() < 0 */  /*    There is a tiny chance that someone was using the overlay and    issued a flip that hasn't finished. To be 100% sure I'll just    take the lock and sleep for the worst case time for a flip.  */  I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);  usleep(20000);  /* 1/50th Sec for 50hz refresh */  /* Set up Overlay regs with Initial Values */  pI810XvMC->oregs->YRGB_VPH = 0;  pI810XvMC->oregs->UV_VPH = 0;  pI810XvMC->oregs->HORZ_PH = 0;  pI810XvMC->oregs->INIT_PH = 0;  pI810XvMC->oregs->DWINPOS = 0;  pI810XvMC->oregs->DWINSZ = (I810_XVMC_MAXHEIGHT << 16) |    I810_XVMC_MAXWIDTH;  pI810XvMC->oregs->SWID =  I810_XVMC_MAXWIDTH | (I810_XVMC_MAXWIDTH << 15);  pI810XvMC->oregs->SWIDQW = (I810_XVMC_MAXWIDTH >> 3) |    (I810_XVMC_MAXWIDTH << 12);  pI810XvMC->oregs->SHEIGHT = I810_XVMC_MAXHEIGHT |    (I810_XVMC_MAXHEIGHT << 15);  pI810XvMC->oregs->YRGBSCALE = 0x80004000; /* scale factor 1 */  pI810XvMC->oregs->UVSCALE = 0x80004000;   /* scale factor 1 */  pI810XvMC->oregs->OV0CLRC0 = 0x4000;      /* brightness: 0 contrast: 1.0 */  pI810XvMC->oregs->OV0CLRC1 = 0x80;        /* saturation: bypass */    /* Destination Colorkey Setup */  pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey);  pI810XvMC->oregs->DCLRKM = 0x80070307;    pI810XvMC->oregs->SCLRKVH = 0;  pI810XvMC->oregs->SCLRKVL = 0;  pI810XvMC->oregs->SCLRKM = 0; /* source color key disable */  pI810XvMC->oregs->OV0CONF = 0; /* two 720 pixel line buffers */    pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |     Y_ADJUST | YUV_420;  pI810XvMC->ref = 1;  I810_UNLOCK(pI810XvMC);  return Success;}/***************************************************************************// Function: XvMCDestroyContext// Description: Destorys the specified context.//// Arguments://   display - Specifies the connection to the server.//   context - The context to be destroyed.//// Returns: Status***************************************************************************/Status XvMCDestroyContext(Display *display, XvMCContext *context) {  i810XvMCContext *pI810XvMC;  if(context == NULL) {    return (error_base + XvMCBadContext);  }  if(context->privData == NULL) {    return (error_base + XvMCBadContext);  }  pI810XvMC = (i810XvMCContext *)context->privData;  /* Turn off the overlay */  if(pI810XvMC->last_flip) {    I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);    /* Make sure last flip is done */    BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);    pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |      Y_ADJUST;    pI810XvMC->current = !pI810XvMC->current;    if(pI810XvMC->current == 1) {      pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0;    }    else {      pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0;    }    OVERLAY_FLIP(pI810XvMC);    pI810XvMC->last_flip++;      /* Wait for the flip */    BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);    I810_UNLOCK(pI810XvMC);  }  /* Pass Control to the X server to destroy the drm_context_t */  _xvmc_destroy_context(display, context);  i810_free_privContext(pI810XvMC);  context->privData = NULL;  return Success;}/***************************************************************************// Function: XvMCCreateSurface***************************************************************************/Status XvMCCreateSurface( Display *display, XvMCContext *context,			  XvMCSurface *surface) {  i810XvMCContext *pI810XvMC;  i810XvMCSurface *pI810Surface;  int priv_count;  uint *priv_data;  Status ret;  if((surface == NULL) || (context == NULL) || (display == NULL)){    return BadValue;  }    pI810XvMC = (i810XvMCContext *)context->privData;  if(pI810XvMC == NULL) {    return (error_base + XvMCBadContext);  }  surface->privData = (i810XvMCSurface *)malloc(sizeof(i810XvMCSurface));  if(!surface->privData) {    return BadAlloc;  }  pI810Surface = (i810XvMCSurface *)surface->privData;  /* Initialize private values */  pI810Surface->privContext = pI810XvMC;  pI810Surface->last_render = 0;

⌨️ 快捷键说明

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