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

📄 damage.c

📁 是由intel提供的针对intel显卡915以上系列的linux驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $Id: damage.c,v 1.1.2.1 2005/09/09 16:09:44 alanh Exp $ * * Copyright © 2003 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission.  Keith Packard makes no * representations about the suitability of this software for any purpose.  It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include    <X11/X.h>#include    "scrnintstr.h"#include    "windowstr.h"#include    "font.h"#include    "dixfontstr.h"#include    "fontstruct.h"#include    "mi.h"#include    "regionstr.h"#include    "globals.h"#include    "gcstruct.h"#include    "damage.h"#include    "damagestr.h"#define wrap(priv, real, mem, func) {\    priv->mem = real->mem; \    real->mem = func; \}#define unwrap(priv, real, mem) {\    real->mem = priv->mem; \}#define BOX_SAME(a,b) \    ((a)->x1 == (b)->x1 && \     (a)->y1 == (b)->y1 && \     (a)->x2 == (b)->x2 && \     (a)->y2 == (b)->y2)#define DAMAGE_DEBUG_ENABLE 0#if DAMAGE_DEBUG_ENABLE#define DAMAGE_DEBUG(x)	ErrorF x#else#define DAMAGE_DEBUG(x)#endifstatic PixmapPtrGetDrawablePixmap (DrawablePtr pDrawable){    ScreenPtr	pScreen = pDrawable->pScreen;    PixmapPtr	pPixmap;    if (pDrawable->type == DRAWABLE_WINDOW)    {	pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);	if (!pPixmap)	    pPixmap = (*pScreen->GetScreenPixmap) (pDrawable->pScreen);    }    else	pPixmap = (PixmapPtr) pDrawable;    return pPixmap;}#define pixmapDamage(pPixmap)	damagePixPriv(pPixmap)#define drawableDamage(pDrawable)	damagePixPriv(GetDrawablePixmap(pDrawable))#define windowDamage(pWin)	drawableDamage(&(pWin)->drawable)#define getDrawableDamage(pDrawable)    damageGetPixPriv(GetDrawablePixmap(pDrawable))#define getWindowDamage(pWin)	    getDrawableDamage(&(pWin)->drawable)#define pixDamageRef(pPixmap) \    DamagePtr	*pPrev = (DamagePtr *) \	    &(pPixmap->devPrivates[damagePixPrivateIndex].ptr)#define winDamageRef(pWindow) \    DamagePtr	*pPrev = (DamagePtr *) \	    &(pWindow->devPrivates[damageWinPrivateIndex].ptr)#if DAMAGE_DEBUG_ENABLEstatic void_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, char *where)#define damageDamageRegion(d,r,c) _damageDamageRegion(d,r,c,__FUNCTION__)#elsestatic voiddamageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip)#endif{    damageScrPriv(pDrawable->pScreen);    drawableDamage(pDrawable);    DamagePtr	    pNext;    RegionPtr	    pClip;    RegionRec	    clippedRec;    RegionPtr	    pDamageRegion;    RegionRec	    pixClip;    Bool	    was_empty;    RegionRec	    tmpRegion;    BoxRec	    tmpBox;    int		    draw_x, draw_y;#ifdef COMPOSITE    int		    screen_x = 0, screen_y = 0;#endif    /* short circuit for empty regions */    if (!REGION_NOTEMPTY(pScreen, pRegion))	return;    #ifdef COMPOSITE    /*     * When drawing to a pixmap which is storing window contents,     * the region presented is in pixmap relative coordinates which     * need to be converted to screen relative coordinates     */    if (pDrawable->type != DRAWABLE_WINDOW)    {	screen_x = ((PixmapPtr) pDrawable)->screen_x;	screen_y = ((PixmapPtr) pDrawable)->screen_y;    }    if (screen_x || screen_y)	REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);#endif	    REGION_INIT (pScreen, &clippedRec, NullBox, 0);    for (; pDamage; pDamage = pNext)    {	pNext = pDamage->pNext;	/*	 * Check for internal damage and don't send events	 */	if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)	{	    DAMAGE_DEBUG (("non internal damage, skipping at %d\n",			   pScrPriv->internalLevel));	    continue;	}	/*	 * Check for unrealized windows	 */	if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&	    !((WindowPtr) (pDamage->pDrawable))->realized)	{	    DAMAGE_DEBUG (("damage while window unrealized\n"));	    continue;	}		draw_x = pDamage->pDrawable->x;	draw_y = pDamage->pDrawable->y;#ifdef COMPOSITE	/*	 * Need to move everyone to screen coordinates	 * XXX what about off-screen pixmaps with non-zero x/y?	 */	if (pDamage->pDrawable->type != DRAWABLE_WINDOW)	{	    draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;	    draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;	}#endif		/*	 * Clip against border or pixmap bounds	 */		pDamageRegion = pRegion;	if (clip || pDamage->pDrawable != pDrawable)	{	    pDamageRegion = &clippedRec;	    if (pDamage->pDrawable->type == DRAWABLE_WINDOW)		pClip = &((WindowPtr)(pDamage->pDrawable))->borderClip;	    else	    {		BoxRec	box;		box.x1 = draw_x;		box.y1 = draw_y;		box.x2 = draw_x + pDamage->pDrawable->width;		box.y2 = draw_y + pDamage->pDrawable->height;		REGION_INIT(pScreen, &pixClip, &box, 1);		pClip = &pixClip;	    }	    REGION_INTERSECT (pScreen, pDamageRegion, pRegion, pClip);	    /*	     * Short circuit empty results	     */	    if (!REGION_NOTEMPTY(pScreen, pDamageRegion))		continue;	}		DAMAGE_DEBUG (("%s %d x %d +%d +%d\n", where,		       pDamageRegion->extents.x2 - pDamageRegion->extents.x1,		       pDamageRegion->extents.y2 - pDamageRegion->extents.y1,		       pDamageRegion->extents.x1, pDamageRegion->extents.y1));		/*	 * Move region to target coordinate space	 */	if (draw_x || draw_y)	    REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);		switch (pDamage->damageLevel) {	case DamageReportRawRegion:	    (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);	    break;	case DamageReportDeltaRegion:	    REGION_INIT (pScreen, &tmpRegion, NullBox, 0);	    REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);	    if (REGION_NOTEMPTY (pScreen, &tmpRegion))	    {		REGION_UNION(pScreen, &pDamage->damage,			     &pDamage->damage, pDamageRegion);		(*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);	    }	    break;	case DamageReportBoundingBox:	    tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);	    REGION_UNION(pScreen, &pDamage->damage,			 &pDamage->damage, pDamageRegion);	    if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);	    break;	case DamageReportNonEmpty:	    was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,			 pDamageRegion);	    if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);	    break;	case DamageReportNone:	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,			 pDamageRegion);	    break;	}	/*	 * translate original region back	 */	if (pDamageRegion == pRegion && (draw_x || draw_y))	    REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);    }#ifdef COMPOSITE    if (screen_x || screen_y)	REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);#endif        REGION_UNINIT (pScreen, &clippedRec);}#if DAMAGE_DEBUG_ENABLE#define damageDamageBox(d,b) _damageDamageBox(d,b,__FUNCTION__)static void_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, char *where)#elsestatic voiddamageDamageBox (DrawablePtr pDrawable, BoxPtr pBox)#endif{    RegionRec	region;    REGION_INIT (pDrawable->pScreen, &region, pBox, 1);#if DAMAGE_DEBUG_ENABLE    _damageDamageRegion (pDrawable, &region, TRUE, where);#else    damageDamageRegion (pDrawable, &region, TRUE);#endif    REGION_UNINIT (pDrawable->pScreen, &region);}static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);static void damageChangeGC(GCPtr, unsigned long);static void damageCopyGC(GCPtr, unsigned long, GCPtr);static void damageDestroyGC(GCPtr);static void damageChangeClip(GCPtr, int, pointer, int);static void damageDestroyClip(GCPtr);static void damageCopyClip(GCPtr, GCPtr);GCFuncs damageGCFuncs = {    damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,    damageChangeClip, damageDestroyClip, damageCopyClip};extern GCOps damageGCOps;static BooldamageCreateGC(GCPtr pGC){    ScreenPtr pScreen = pGC->pScreen;    damageScrPriv(pScreen);    damageGCPriv(pGC);    Bool ret;    unwrap (pScrPriv, pScreen, CreateGC);    if((ret = (*pScreen->CreateGC) (pGC))) {	pGCPriv->ops = NULL;	pGCPriv->funcs = pGC->funcs;	pGC->funcs = &damageGCFuncs;    }    wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);    return ret;}#if NOTUSEDstatic voiddamageWrapGC (GCPtr pGC){    damageGCPriv(pGC);    pGCPriv->ops = NULL;    pGCPriv->funcs = pGC->funcs;    pGC->funcs = &damageGCFuncs;}static voiddamageUnwrapGC (GCPtr pGC){    damageGCPriv(pGC);    pGC->funcs = pGCPriv->funcs;    if (pGCPriv->ops)	pGC->ops = pGCPriv->ops;}#endif#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \    damageGCPriv(pGC);  \    GCFuncs *oldFuncs = pGC->funcs; \    unwrap(pGCPriv, pGC, funcs);  \    unwrap(pGCPriv, pGC, ops); \#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \    wrap(pGCPriv, pGC, funcs, oldFuncs); \    wrap(pGCPriv, pGC, ops, &damageGCOps)#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \    damageGCPriv(pGC); \    unwrap(pGCPriv, pGC, funcs); \    if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \    wrap(pGCPriv, pGC, funcs, &damageGCFuncs);  \    if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)static voiddamageValidateGC(GCPtr         pGC,		 unsigned long changes,		 DrawablePtr   pDrawable){    DAMAGE_GC_FUNC_PROLOGUE (pGC);    (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);    pGCPriv->ops = pGC->ops;  /* just so it's not NULL */    DAMAGE_GC_FUNC_EPILOGUE (pGC);}static voiddamageDestroyGC(GCPtr pGC){    DAMAGE_GC_FUNC_PROLOGUE (pGC);    (*pGC->funcs->DestroyGC)(pGC);    DAMAGE_GC_FUNC_EPILOGUE (pGC);}static voiddamageChangeGC (GCPtr		pGC,		unsigned long   mask){    DAMAGE_GC_FUNC_PROLOGUE (pGC);    (*pGC->funcs->ChangeGC) (pGC, mask);    DAMAGE_GC_FUNC_EPILOGUE (pGC);}static voiddamageCopyGC (GCPtr	    pGCSrc,	      unsigned long mask,	      GCPtr	    pGCDst){    DAMAGE_GC_FUNC_PROLOGUE (pGCDst);    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);    DAMAGE_GC_FUNC_EPILOGUE (pGCDst);}static voiddamageChangeClip (GCPtr	    pGC,		  int	    type,		  pointer   pvalue,		  int	    nrects){    DAMAGE_GC_FUNC_PROLOGUE (pGC);    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);    DAMAGE_GC_FUNC_EPILOGUE (pGC);}static voiddamageCopyClip(GCPtr pgcDst, GCPtr pgcSrc){    DAMAGE_GC_FUNC_PROLOGUE (pgcDst);    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);    DAMAGE_GC_FUNC_EPILOGUE (pgcDst);}static voiddamageDestroyClip(GCPtr pGC){    DAMAGE_GC_FUNC_PROLOGUE (pGC);    (* pGC->funcs->DestroyClip)(pGC);    DAMAGE_GC_FUNC_EPILOGUE (pGC);}#define TRIM_BOX(box, pGC) { \    BoxPtr extents = &pGC->pCompositeClip->extents;\    if(box.x1 < extents->x1) box.x1 = extents->x1; \    if(box.x2 > extents->x2) box.x2 = extents->x2; \    if(box.y1 < extents->y1) box.y1 = extents->y1; \    if(box.y2 > extents->y2) box.y2 = extents->y2; \    }#define TRANSLATE_BOX(box, pDrawable) { \    box.x1 += pDrawable->x; \    box.x2 += pDrawable->x; \    box.y1 += pDrawable->y; \    box.y2 += pDrawable->y; \    }#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \    TRANSLATE_BOX(box, pDrawable); \    TRIM_BOX(box, pGC); \    }#define BOX_NOT_EMPTY(box) \    (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))#define checkGCDamage(d,g)	(getDrawableDamage(d) && \				 REGION_NOTEMPTY(pScreen, g->pCompositeClip))#ifdef RENDER#define TRIM_PICTURE_BOX(box, pDst) { \    BoxPtr extents = &pDst->pCompositeClip->extents;\    if(box.x1 < extents->x1) box.x1 = extents->x1; \    if(box.x2 > extents->x2) box.x2 = extents->x2; \    if(box.y1 < extents->y1) box.y1 = extents->y1; \    if(box.y2 > extents->y2) box.y2 = extents->y2; \    }    #define checkPictureDamage(p)	(getDrawableDamage(p->pDrawable) && \				 REGION_NOTEMPTY(pScreen, p->pCompositeClip))static voiddamageComposite (CARD8      op,		   PicturePtr pSrc,		   PicturePtr pMask,		   PicturePtr pDst,		   INT16      xSrc,		   INT16      ySrc,		   INT16      xMask,		   INT16      yMask,		   INT16      xDst,		   INT16      yDst,		   CARD16     width,		   CARD16     height){    ScreenPtr		pScreen = pDst->pDrawable->pScreen;    PictureScreenPtr	ps = GetPictureScreen(pScreen);    damageScrPriv(pScreen);    if (checkPictureDamage (pDst))    {	BoxRec	box;	box.x1 = xDst + pDst->pDrawable->x;	box.y1 = yDst + pDst->pDrawable->y;	box.x2 = box.x1 + width;	box.y2 = box.y1 + height;	TRIM_PICTURE_BOX(box, pDst);	if (BOX_NOT_EMPTY(box))	    damageDamageBox (pDst->pDrawable, &box);    }    unwrap (pScrPriv, ps, Composite);    (*ps->Composite) (op,		       pSrc,		       pMask,		       pDst,		       xSrc,		       ySrc,		       xMask,		       yMask,		       xDst,		       yDst,		       width,		       height);    wrap (pScrPriv, ps, Composite, damageComposite);}static voiddamageGlyphs (CARD8		op,		PicturePtr	pSrc,		PicturePtr	pDst,		PictFormatPtr	maskFormat,		INT16		xSrc,		INT16		ySrc,		int		nlist,		GlyphListPtr	list,		GlyphPtr	*glyphs){    ScreenPtr		pScreen = pDst->pDrawable->pScreen;    PictureScreenPtr	ps = GetPictureScreen(pScreen);    damageScrPriv(pScreen);    if (checkPictureDamage (pDst))    {	int		nlistTmp = nlist;	GlyphListPtr	listTmp = list;	GlyphPtr	*glyphsTmp = glyphs;	int		x, y;	int		n;	GlyphPtr	glyph;	BoxRec		box;	int		x1, y1, x2, y2;	box.x1 = 32767;	box.y1 = 32767;	box.x2 = -32767;	box.y2 = -32767;	x = pDst->pDrawable->x;	y = pDst->pDrawable->y;	while (nlistTmp--)	{	    x += listTmp->xOff;	    y += listTmp->yOff;	    n = listTmp->len;	    while (n--)	    {		glyph = *glyphsTmp++;		x1 = x - glyph->info.x;		y1 = y - glyph->info.y;		x2 = x1 + glyph->info.width;		y2 = y1 + glyph->info.height;		if (x1 < box.x1)		    box.x1 = x1;		if (y1 < box.y1)		    box.y1 = y1;		if (x2 > box.x2)		    box.x2 = x2;		if (y2 > box.y2)		    box.y2 = y2;		x += glyph->info.xOff;		y += glyph->info.yOff;	    }	    listTmp++;	}	TRIM_PICTURE_BOX (box, pDst);	if (BOX_NOT_EMPTY(box))	    damageDamageBox (pDst->pDrawable, &box);    }    unwrap (pScrPriv, ps, Glyphs);    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);    wrap (pScrPriv, ps, Glyphs, damageGlyphs);}#endif/**********************************************************/static voiddamageFillSpans(DrawablePtr pDrawable,		GC	    *pGC,		int	    npt,		DDXPointPtr ppt,		int	    *pwidth,		int	    fSorted){    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);    if (npt && checkGCDamage (pDrawable, pGC))    {	int	    nptTmp = npt;	DDXPointPtr pptTmp = ppt;	int	    *pwidthTmp = pwidth;	BoxRec	    box;	box.x1 = pptTmp->x;	box.x2 = box.x1 + *pwidthTmp;	box.y2 = box.y1 = pptTmp->y;	while(--nptTmp) 	{	   pptTmp++;	   pwidthTmp++;	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;	   if(box.x2 < (pptTmp->x + *pwidthTmp))		box.x2 = pptTmp->x + *pwidthTmp;	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;	}	box.y2++;        if(!pGC->miTranslate) {           TRANSLATE_BOX(box, pDrawable);        }        TRIM_BOX(box, pGC); 	if(BOX_NOT_EMPTY(box))	   damageDamageBox (pDrawable, &box);    }        (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);

⌨️ 快捷键说明

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